@cruxy/cli 0.17.0 → 0.19.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/dist/agent/loop.d.ts +15 -0
- package/dist/agent/loop.js +21 -0
- package/dist/agent/prompts.d.ts +7 -0
- package/dist/agent/prompts.js +6 -0
- package/dist/agent/session.d.ts +26 -1
- package/dist/agent/session.js +39 -6
- package/dist/cli/commands/memory.d.ts +8 -0
- package/dist/cli/commands/memory.js +98 -0
- package/dist/cli/commands/run.js +19 -0
- package/dist/cli/commands/usage.d.ts +9 -0
- package/dist/cli/commands/usage.js +81 -0
- package/dist/cli/program.js +4 -0
- package/dist/cli/session-factory.js +39 -1
- package/dist/config/schema.d.ts +336 -12
- package/dist/config/schema.js +56 -0
- package/dist/constants.d.ts +18 -0
- package/dist/constants.js +18 -0
- package/dist/errors/constructors.d.ts +21 -0
- package/dist/errors/constructors.js +64 -0
- package/dist/errors/types.d.ts +12 -0
- package/dist/errors/types.js +24 -0
- package/dist/hooks/types.d.ts +1 -1
- package/dist/memory/index.d.ts +7 -0
- package/dist/memory/index.js +7 -0
- package/dist/memory/recall.d.ts +32 -0
- package/dist/memory/recall.js +73 -0
- package/dist/memory/remember-tool.d.ts +25 -0
- package/dist/memory/remember-tool.js +56 -0
- package/dist/memory/secrets.d.ts +29 -0
- package/dist/memory/secrets.js +61 -0
- package/dist/memory/service.d.ts +92 -0
- package/dist/memory/service.js +164 -0
- package/dist/memory/store.d.ts +32 -0
- package/dist/memory/store.js +100 -0
- package/dist/memory/trust.d.ts +52 -0
- package/dist/memory/trust.js +106 -0
- package/dist/memory/types.d.ts +101 -0
- package/dist/memory/types.js +58 -0
- package/dist/plan/service.d.ts +13 -1
- package/dist/plan/service.js +4 -0
- package/dist/usage/collect.d.ts +40 -0
- package/dist/usage/collect.js +34 -0
- package/dist/usage/cost.d.ts +19 -0
- package/dist/usage/cost.js +29 -0
- package/dist/usage/index.d.ts +15 -0
- package/dist/usage/index.js +15 -0
- package/dist/usage/store.d.ts +37 -0
- package/dist/usage/store.js +83 -0
- package/dist/usage/summary.d.ts +32 -0
- package/dist/usage/summary.js +119 -0
- package/dist/usage/types.d.ts +220 -0
- package/dist/usage/types.js +47 -0
- package/package.json +1 -1
package/dist/config/schema.d.ts
CHANGED
|
@@ -182,7 +182,7 @@ export declare const IndexConfigSchema: z.ZodObject<{
|
|
|
182
182
|
};
|
|
183
183
|
enabled: boolean;
|
|
184
184
|
embedder: "fastembed";
|
|
185
|
-
store: "
|
|
185
|
+
store: "memory" | "auto" | "sqlite";
|
|
186
186
|
maxFileBytes: number;
|
|
187
187
|
chunk: {
|
|
188
188
|
windowLines: number;
|
|
@@ -196,7 +196,7 @@ export declare const IndexConfigSchema: z.ZodObject<{
|
|
|
196
196
|
} | undefined;
|
|
197
197
|
enabled?: boolean | undefined;
|
|
198
198
|
embedder?: "fastembed" | undefined;
|
|
199
|
-
store?: "
|
|
199
|
+
store?: "memory" | "auto" | "sqlite" | undefined;
|
|
200
200
|
maxFileBytes?: number | undefined;
|
|
201
201
|
chunk?: {
|
|
202
202
|
windowLines?: number | undefined;
|
|
@@ -320,18 +320,18 @@ export declare const SandboxConfigSchema: z.ZodObject<{
|
|
|
320
320
|
*/
|
|
321
321
|
mounts: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
322
322
|
}, "strict", z.ZodTypeAny, {
|
|
323
|
+
memory: string;
|
|
323
324
|
image: string;
|
|
324
325
|
enabled: boolean;
|
|
325
|
-
memory: string;
|
|
326
326
|
network: "none" | "host-loopback" | "full";
|
|
327
327
|
pids: number;
|
|
328
328
|
cpus: number;
|
|
329
329
|
mounts: string[];
|
|
330
330
|
timeout?: number | undefined;
|
|
331
331
|
}, {
|
|
332
|
+
memory?: string | undefined;
|
|
332
333
|
image?: string | undefined;
|
|
333
334
|
enabled?: boolean | undefined;
|
|
334
|
-
memory?: string | undefined;
|
|
335
335
|
network?: "none" | "host-loopback" | "full" | undefined;
|
|
336
336
|
pids?: number | undefined;
|
|
337
337
|
cpus?: number | undefined;
|
|
@@ -386,6 +386,160 @@ export declare const RoutingConfigSchema: z.ZodObject<{
|
|
|
386
386
|
map?: Partial<Record<"main-turn" | "subagent" | "plan" | "commit-msg" | "classify" | "summarize", "kavi" | "vaani" | "mira">> | undefined;
|
|
387
387
|
default?: "kavi" | "vaani" | "mira" | undefined;
|
|
388
388
|
}>;
|
|
389
|
+
/**
|
|
390
|
+
* Persistent memory (C.29): structured notes recalled across sessions. ON by
|
|
391
|
+
* default and safe to be so — user memory is self-authored (nothing you didn't
|
|
392
|
+
* write is injected) and project memory still requires an explicit
|
|
393
|
+
* `cruxy memory trust`, so a cloned repo never auto-injects. Recall is bounded
|
|
394
|
+
* by a token budget; the `remember` tool refuses to persist secrets.
|
|
395
|
+
*/
|
|
396
|
+
export declare const MemoryConfigSchema: z.ZodObject<{
|
|
397
|
+
/** Master switch. When false, nothing is recalled and the `remember` tool
|
|
398
|
+
* is not registered (memory stays fully inert). */
|
|
399
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
400
|
+
/** Token budget for the recalled block injected at session start; entries
|
|
401
|
+
* beyond it are pruned oldest-first (the omission is stated, never silent). */
|
|
402
|
+
maxRecallTokens: z.ZodDefault<z.ZodNumber>;
|
|
403
|
+
}, "strict", z.ZodTypeAny, {
|
|
404
|
+
enabled: boolean;
|
|
405
|
+
maxRecallTokens: number;
|
|
406
|
+
}, {
|
|
407
|
+
enabled?: boolean | undefined;
|
|
408
|
+
maxRecallTokens?: number | undefined;
|
|
409
|
+
}>;
|
|
410
|
+
export type MemoryConfig = z.infer<typeof MemoryConfigSchema>;
|
|
411
|
+
/** A per-tier price, in the user's own currency, PER MILLION TOKENS (C.22). */
|
|
412
|
+
export declare const TierPriceSchema: z.ZodObject<{
|
|
413
|
+
/** Price per 1,000,000 input tokens. */
|
|
414
|
+
input: z.ZodNumber;
|
|
415
|
+
/** Price per 1,000,000 output tokens. */
|
|
416
|
+
output: z.ZodNumber;
|
|
417
|
+
}, "strict", z.ZodTypeAny, {
|
|
418
|
+
input: number;
|
|
419
|
+
output: number;
|
|
420
|
+
}, {
|
|
421
|
+
input: number;
|
|
422
|
+
output: number;
|
|
423
|
+
}>;
|
|
424
|
+
/**
|
|
425
|
+
* Usage telemetry + cost tracking (C.22): LOCAL usage accounting only — nothing
|
|
426
|
+
* here is ever transmitted. Costs are opt-in and honest: prices are per-TIER and
|
|
427
|
+
* per-million-tokens, configured by the user; with none set, tokens are shown
|
|
428
|
+
* and cost is omitted (cruxy ships no bundled price table). The `prices` keys are
|
|
429
|
+
* the fixed {@link MODEL_TIERS}, so an upstream model name can never appear here
|
|
430
|
+
* (U.8 gag holds by construction) and a mistyped tier is rejected at config load.
|
|
431
|
+
*/
|
|
432
|
+
export declare const UsageConfigSchema: z.ZodObject<{
|
|
433
|
+
/** Master switch. When false, no usage is collected, persisted, or shown. */
|
|
434
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
435
|
+
/** Currency label to prefix costs with (e.g. "$", "€"). Empty ⇒ no symbol is
|
|
436
|
+
* assumed — a bare number is shown, since the user configured the prices. */
|
|
437
|
+
currency: z.ZodDefault<z.ZodString>;
|
|
438
|
+
/** How many past runs to keep in the store; older ones are pruned oldest-first. */
|
|
439
|
+
retention: z.ZodDefault<z.ZodNumber>;
|
|
440
|
+
/** Per-tier prices. Any tier omitted is simply unpriced (cost omitted for it). */
|
|
441
|
+
prices: z.ZodDefault<z.ZodObject<{
|
|
442
|
+
kavi: z.ZodOptional<z.ZodObject<{
|
|
443
|
+
/** Price per 1,000,000 input tokens. */
|
|
444
|
+
input: z.ZodNumber;
|
|
445
|
+
/** Price per 1,000,000 output tokens. */
|
|
446
|
+
output: z.ZodNumber;
|
|
447
|
+
}, "strict", z.ZodTypeAny, {
|
|
448
|
+
input: number;
|
|
449
|
+
output: number;
|
|
450
|
+
}, {
|
|
451
|
+
input: number;
|
|
452
|
+
output: number;
|
|
453
|
+
}>>;
|
|
454
|
+
vaani: z.ZodOptional<z.ZodObject<{
|
|
455
|
+
/** Price per 1,000,000 input tokens. */
|
|
456
|
+
input: z.ZodNumber;
|
|
457
|
+
/** Price per 1,000,000 output tokens. */
|
|
458
|
+
output: z.ZodNumber;
|
|
459
|
+
}, "strict", z.ZodTypeAny, {
|
|
460
|
+
input: number;
|
|
461
|
+
output: number;
|
|
462
|
+
}, {
|
|
463
|
+
input: number;
|
|
464
|
+
output: number;
|
|
465
|
+
}>>;
|
|
466
|
+
mira: z.ZodOptional<z.ZodObject<{
|
|
467
|
+
/** Price per 1,000,000 input tokens. */
|
|
468
|
+
input: z.ZodNumber;
|
|
469
|
+
/** Price per 1,000,000 output tokens. */
|
|
470
|
+
output: z.ZodNumber;
|
|
471
|
+
}, "strict", z.ZodTypeAny, {
|
|
472
|
+
input: number;
|
|
473
|
+
output: number;
|
|
474
|
+
}, {
|
|
475
|
+
input: number;
|
|
476
|
+
output: number;
|
|
477
|
+
}>>;
|
|
478
|
+
}, "strict", z.ZodTypeAny, {
|
|
479
|
+
kavi?: {
|
|
480
|
+
input: number;
|
|
481
|
+
output: number;
|
|
482
|
+
} | undefined;
|
|
483
|
+
vaani?: {
|
|
484
|
+
input: number;
|
|
485
|
+
output: number;
|
|
486
|
+
} | undefined;
|
|
487
|
+
mira?: {
|
|
488
|
+
input: number;
|
|
489
|
+
output: number;
|
|
490
|
+
} | undefined;
|
|
491
|
+
}, {
|
|
492
|
+
kavi?: {
|
|
493
|
+
input: number;
|
|
494
|
+
output: number;
|
|
495
|
+
} | undefined;
|
|
496
|
+
vaani?: {
|
|
497
|
+
input: number;
|
|
498
|
+
output: number;
|
|
499
|
+
} | undefined;
|
|
500
|
+
mira?: {
|
|
501
|
+
input: number;
|
|
502
|
+
output: number;
|
|
503
|
+
} | undefined;
|
|
504
|
+
}>>;
|
|
505
|
+
}, "strict", z.ZodTypeAny, {
|
|
506
|
+
enabled: boolean;
|
|
507
|
+
retention: number;
|
|
508
|
+
currency: string;
|
|
509
|
+
prices: {
|
|
510
|
+
kavi?: {
|
|
511
|
+
input: number;
|
|
512
|
+
output: number;
|
|
513
|
+
} | undefined;
|
|
514
|
+
vaani?: {
|
|
515
|
+
input: number;
|
|
516
|
+
output: number;
|
|
517
|
+
} | undefined;
|
|
518
|
+
mira?: {
|
|
519
|
+
input: number;
|
|
520
|
+
output: number;
|
|
521
|
+
} | undefined;
|
|
522
|
+
};
|
|
523
|
+
}, {
|
|
524
|
+
enabled?: boolean | undefined;
|
|
525
|
+
retention?: number | undefined;
|
|
526
|
+
currency?: string | undefined;
|
|
527
|
+
prices?: {
|
|
528
|
+
kavi?: {
|
|
529
|
+
input: number;
|
|
530
|
+
output: number;
|
|
531
|
+
} | undefined;
|
|
532
|
+
vaani?: {
|
|
533
|
+
input: number;
|
|
534
|
+
output: number;
|
|
535
|
+
} | undefined;
|
|
536
|
+
mira?: {
|
|
537
|
+
input: number;
|
|
538
|
+
output: number;
|
|
539
|
+
} | undefined;
|
|
540
|
+
} | undefined;
|
|
541
|
+
}>;
|
|
542
|
+
export type UsageConfig = z.infer<typeof UsageConfigSchema>;
|
|
389
543
|
/** MCP server entry — stdio or URL transport (wired up in a later phase). */
|
|
390
544
|
export declare const McpServerSchema: z.ZodObject<{
|
|
391
545
|
command: z.ZodOptional<z.ZodString>;
|
|
@@ -567,7 +721,7 @@ export declare const CruxyConfigSchema: z.ZodObject<{
|
|
|
567
721
|
};
|
|
568
722
|
enabled: boolean;
|
|
569
723
|
embedder: "fastembed";
|
|
570
|
-
store: "
|
|
724
|
+
store: "memory" | "auto" | "sqlite";
|
|
571
725
|
maxFileBytes: number;
|
|
572
726
|
chunk: {
|
|
573
727
|
windowLines: number;
|
|
@@ -581,7 +735,7 @@ export declare const CruxyConfigSchema: z.ZodObject<{
|
|
|
581
735
|
} | undefined;
|
|
582
736
|
enabled?: boolean | undefined;
|
|
583
737
|
embedder?: "fastembed" | undefined;
|
|
584
|
-
store?: "
|
|
738
|
+
store?: "memory" | "auto" | "sqlite" | undefined;
|
|
585
739
|
maxFileBytes?: number | undefined;
|
|
586
740
|
chunk?: {
|
|
587
741
|
windowLines?: number | undefined;
|
|
@@ -683,18 +837,18 @@ export declare const CruxyConfigSchema: z.ZodObject<{
|
|
|
683
837
|
*/
|
|
684
838
|
mounts: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
685
839
|
}, "strict", z.ZodTypeAny, {
|
|
840
|
+
memory: string;
|
|
686
841
|
image: string;
|
|
687
842
|
enabled: boolean;
|
|
688
|
-
memory: string;
|
|
689
843
|
network: "none" | "host-loopback" | "full";
|
|
690
844
|
pids: number;
|
|
691
845
|
cpus: number;
|
|
692
846
|
mounts: string[];
|
|
693
847
|
timeout?: number | undefined;
|
|
694
848
|
}, {
|
|
849
|
+
memory?: string | undefined;
|
|
695
850
|
image?: string | undefined;
|
|
696
851
|
enabled?: boolean | undefined;
|
|
697
|
-
memory?: string | undefined;
|
|
698
852
|
network?: "none" | "host-loopback" | "full" | undefined;
|
|
699
853
|
pids?: number | undefined;
|
|
700
854
|
cpus?: number | undefined;
|
|
@@ -731,6 +885,130 @@ export declare const CruxyConfigSchema: z.ZodObject<{
|
|
|
731
885
|
map?: Partial<Record<"main-turn" | "subagent" | "plan" | "commit-msg" | "classify" | "summarize", "kavi" | "vaani" | "mira">> | undefined;
|
|
732
886
|
default?: "kavi" | "vaani" | "mira" | undefined;
|
|
733
887
|
}>>;
|
|
888
|
+
memory: z.ZodDefault<z.ZodObject<{
|
|
889
|
+
/** Master switch. When false, nothing is recalled and the `remember` tool
|
|
890
|
+
* is not registered (memory stays fully inert). */
|
|
891
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
892
|
+
/** Token budget for the recalled block injected at session start; entries
|
|
893
|
+
* beyond it are pruned oldest-first (the omission is stated, never silent). */
|
|
894
|
+
maxRecallTokens: z.ZodDefault<z.ZodNumber>;
|
|
895
|
+
}, "strict", z.ZodTypeAny, {
|
|
896
|
+
enabled: boolean;
|
|
897
|
+
maxRecallTokens: number;
|
|
898
|
+
}, {
|
|
899
|
+
enabled?: boolean | undefined;
|
|
900
|
+
maxRecallTokens?: number | undefined;
|
|
901
|
+
}>>;
|
|
902
|
+
usage: z.ZodDefault<z.ZodObject<{
|
|
903
|
+
/** Master switch. When false, no usage is collected, persisted, or shown. */
|
|
904
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
905
|
+
/** Currency label to prefix costs with (e.g. "$", "€"). Empty ⇒ no symbol is
|
|
906
|
+
* assumed — a bare number is shown, since the user configured the prices. */
|
|
907
|
+
currency: z.ZodDefault<z.ZodString>;
|
|
908
|
+
/** How many past runs to keep in the store; older ones are pruned oldest-first. */
|
|
909
|
+
retention: z.ZodDefault<z.ZodNumber>;
|
|
910
|
+
/** Per-tier prices. Any tier omitted is simply unpriced (cost omitted for it). */
|
|
911
|
+
prices: z.ZodDefault<z.ZodObject<{
|
|
912
|
+
kavi: z.ZodOptional<z.ZodObject<{
|
|
913
|
+
/** Price per 1,000,000 input tokens. */
|
|
914
|
+
input: z.ZodNumber;
|
|
915
|
+
/** Price per 1,000,000 output tokens. */
|
|
916
|
+
output: z.ZodNumber;
|
|
917
|
+
}, "strict", z.ZodTypeAny, {
|
|
918
|
+
input: number;
|
|
919
|
+
output: number;
|
|
920
|
+
}, {
|
|
921
|
+
input: number;
|
|
922
|
+
output: number;
|
|
923
|
+
}>>;
|
|
924
|
+
vaani: z.ZodOptional<z.ZodObject<{
|
|
925
|
+
/** Price per 1,000,000 input tokens. */
|
|
926
|
+
input: z.ZodNumber;
|
|
927
|
+
/** Price per 1,000,000 output tokens. */
|
|
928
|
+
output: z.ZodNumber;
|
|
929
|
+
}, "strict", z.ZodTypeAny, {
|
|
930
|
+
input: number;
|
|
931
|
+
output: number;
|
|
932
|
+
}, {
|
|
933
|
+
input: number;
|
|
934
|
+
output: number;
|
|
935
|
+
}>>;
|
|
936
|
+
mira: z.ZodOptional<z.ZodObject<{
|
|
937
|
+
/** Price per 1,000,000 input tokens. */
|
|
938
|
+
input: z.ZodNumber;
|
|
939
|
+
/** Price per 1,000,000 output tokens. */
|
|
940
|
+
output: z.ZodNumber;
|
|
941
|
+
}, "strict", z.ZodTypeAny, {
|
|
942
|
+
input: number;
|
|
943
|
+
output: number;
|
|
944
|
+
}, {
|
|
945
|
+
input: number;
|
|
946
|
+
output: number;
|
|
947
|
+
}>>;
|
|
948
|
+
}, "strict", z.ZodTypeAny, {
|
|
949
|
+
kavi?: {
|
|
950
|
+
input: number;
|
|
951
|
+
output: number;
|
|
952
|
+
} | undefined;
|
|
953
|
+
vaani?: {
|
|
954
|
+
input: number;
|
|
955
|
+
output: number;
|
|
956
|
+
} | undefined;
|
|
957
|
+
mira?: {
|
|
958
|
+
input: number;
|
|
959
|
+
output: number;
|
|
960
|
+
} | undefined;
|
|
961
|
+
}, {
|
|
962
|
+
kavi?: {
|
|
963
|
+
input: number;
|
|
964
|
+
output: number;
|
|
965
|
+
} | undefined;
|
|
966
|
+
vaani?: {
|
|
967
|
+
input: number;
|
|
968
|
+
output: number;
|
|
969
|
+
} | undefined;
|
|
970
|
+
mira?: {
|
|
971
|
+
input: number;
|
|
972
|
+
output: number;
|
|
973
|
+
} | undefined;
|
|
974
|
+
}>>;
|
|
975
|
+
}, "strict", z.ZodTypeAny, {
|
|
976
|
+
enabled: boolean;
|
|
977
|
+
retention: number;
|
|
978
|
+
currency: string;
|
|
979
|
+
prices: {
|
|
980
|
+
kavi?: {
|
|
981
|
+
input: number;
|
|
982
|
+
output: number;
|
|
983
|
+
} | undefined;
|
|
984
|
+
vaani?: {
|
|
985
|
+
input: number;
|
|
986
|
+
output: number;
|
|
987
|
+
} | undefined;
|
|
988
|
+
mira?: {
|
|
989
|
+
input: number;
|
|
990
|
+
output: number;
|
|
991
|
+
} | undefined;
|
|
992
|
+
};
|
|
993
|
+
}, {
|
|
994
|
+
enabled?: boolean | undefined;
|
|
995
|
+
retention?: number | undefined;
|
|
996
|
+
currency?: string | undefined;
|
|
997
|
+
prices?: {
|
|
998
|
+
kavi?: {
|
|
999
|
+
input: number;
|
|
1000
|
+
output: number;
|
|
1001
|
+
} | undefined;
|
|
1002
|
+
vaani?: {
|
|
1003
|
+
input: number;
|
|
1004
|
+
output: number;
|
|
1005
|
+
} | undefined;
|
|
1006
|
+
mira?: {
|
|
1007
|
+
input: number;
|
|
1008
|
+
output: number;
|
|
1009
|
+
} | undefined;
|
|
1010
|
+
} | undefined;
|
|
1011
|
+
}>>;
|
|
734
1012
|
mcpServers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
735
1013
|
command: z.ZodOptional<z.ZodString>;
|
|
736
1014
|
args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
@@ -749,14 +1027,37 @@ export declare const CruxyConfigSchema: z.ZodObject<{
|
|
|
749
1027
|
cruxy: {
|
|
750
1028
|
gatewayUrl: string;
|
|
751
1029
|
};
|
|
1030
|
+
memory: {
|
|
1031
|
+
enabled: boolean;
|
|
1032
|
+
maxRecallTokens: number;
|
|
1033
|
+
};
|
|
1034
|
+
usage: {
|
|
1035
|
+
enabled: boolean;
|
|
1036
|
+
retention: number;
|
|
1037
|
+
currency: string;
|
|
1038
|
+
prices: {
|
|
1039
|
+
kavi?: {
|
|
1040
|
+
input: number;
|
|
1041
|
+
output: number;
|
|
1042
|
+
} | undefined;
|
|
1043
|
+
vaani?: {
|
|
1044
|
+
input: number;
|
|
1045
|
+
output: number;
|
|
1046
|
+
} | undefined;
|
|
1047
|
+
mira?: {
|
|
1048
|
+
input: number;
|
|
1049
|
+
output: number;
|
|
1050
|
+
} | undefined;
|
|
1051
|
+
};
|
|
1052
|
+
};
|
|
752
1053
|
checkpoint: {
|
|
753
1054
|
enabled: boolean;
|
|
754
1055
|
retention: number;
|
|
755
1056
|
};
|
|
756
1057
|
sandbox: {
|
|
1058
|
+
memory: string;
|
|
757
1059
|
image: string;
|
|
758
1060
|
enabled: boolean;
|
|
759
|
-
memory: string;
|
|
760
1061
|
network: "none" | "host-loopback" | "full";
|
|
761
1062
|
pids: number;
|
|
762
1063
|
cpus: number;
|
|
@@ -812,7 +1113,7 @@ export declare const CruxyConfigSchema: z.ZodObject<{
|
|
|
812
1113
|
};
|
|
813
1114
|
enabled: boolean;
|
|
814
1115
|
embedder: "fastembed";
|
|
815
|
-
store: "
|
|
1116
|
+
store: "memory" | "auto" | "sqlite";
|
|
816
1117
|
maxFileBytes: number;
|
|
817
1118
|
chunk: {
|
|
818
1119
|
windowLines: number;
|
|
@@ -842,14 +1143,37 @@ export declare const CruxyConfigSchema: z.ZodObject<{
|
|
|
842
1143
|
cruxy?: {
|
|
843
1144
|
gatewayUrl?: string | undefined;
|
|
844
1145
|
} | undefined;
|
|
1146
|
+
memory?: {
|
|
1147
|
+
enabled?: boolean | undefined;
|
|
1148
|
+
maxRecallTokens?: number | undefined;
|
|
1149
|
+
} | undefined;
|
|
1150
|
+
usage?: {
|
|
1151
|
+
enabled?: boolean | undefined;
|
|
1152
|
+
retention?: number | undefined;
|
|
1153
|
+
currency?: string | undefined;
|
|
1154
|
+
prices?: {
|
|
1155
|
+
kavi?: {
|
|
1156
|
+
input: number;
|
|
1157
|
+
output: number;
|
|
1158
|
+
} | undefined;
|
|
1159
|
+
vaani?: {
|
|
1160
|
+
input: number;
|
|
1161
|
+
output: number;
|
|
1162
|
+
} | undefined;
|
|
1163
|
+
mira?: {
|
|
1164
|
+
input: number;
|
|
1165
|
+
output: number;
|
|
1166
|
+
} | undefined;
|
|
1167
|
+
} | undefined;
|
|
1168
|
+
} | undefined;
|
|
845
1169
|
checkpoint?: {
|
|
846
1170
|
enabled?: boolean | undefined;
|
|
847
1171
|
retention?: number | undefined;
|
|
848
1172
|
} | undefined;
|
|
849
1173
|
sandbox?: {
|
|
1174
|
+
memory?: string | undefined;
|
|
850
1175
|
image?: string | undefined;
|
|
851
1176
|
enabled?: boolean | undefined;
|
|
852
|
-
memory?: string | undefined;
|
|
853
1177
|
network?: "none" | "host-loopback" | "full" | undefined;
|
|
854
1178
|
pids?: number | undefined;
|
|
855
1179
|
cpus?: number | undefined;
|
|
@@ -905,7 +1229,7 @@ export declare const CruxyConfigSchema: z.ZodObject<{
|
|
|
905
1229
|
} | undefined;
|
|
906
1230
|
enabled?: boolean | undefined;
|
|
907
1231
|
embedder?: "fastembed" | undefined;
|
|
908
|
-
store?: "
|
|
1232
|
+
store?: "memory" | "auto" | "sqlite" | undefined;
|
|
909
1233
|
maxFileBytes?: number | undefined;
|
|
910
1234
|
chunk?: {
|
|
911
1235
|
windowLines?: number | undefined;
|
package/dist/config/schema.js
CHANGED
|
@@ -273,6 +273,60 @@ export const RoutingConfigSchema = z
|
|
|
273
273
|
map: z.record(z.enum(TASK_CLASSES), z.enum(MODEL_TIERS)).default({}),
|
|
274
274
|
})
|
|
275
275
|
.strict();
|
|
276
|
+
/**
|
|
277
|
+
* Persistent memory (C.29): structured notes recalled across sessions. ON by
|
|
278
|
+
* default and safe to be so — user memory is self-authored (nothing you didn't
|
|
279
|
+
* write is injected) and project memory still requires an explicit
|
|
280
|
+
* `cruxy memory trust`, so a cloned repo never auto-injects. Recall is bounded
|
|
281
|
+
* by a token budget; the `remember` tool refuses to persist secrets.
|
|
282
|
+
*/
|
|
283
|
+
export const MemoryConfigSchema = z
|
|
284
|
+
.object({
|
|
285
|
+
/** Master switch. When false, nothing is recalled and the `remember` tool
|
|
286
|
+
* is not registered (memory stays fully inert). */
|
|
287
|
+
enabled: z.boolean().default(true),
|
|
288
|
+
/** Token budget for the recalled block injected at session start; entries
|
|
289
|
+
* beyond it are pruned oldest-first (the omission is stated, never silent). */
|
|
290
|
+
maxRecallTokens: z.number().int().positive().default(1000),
|
|
291
|
+
})
|
|
292
|
+
.strict();
|
|
293
|
+
/** A per-tier price, in the user's own currency, PER MILLION TOKENS (C.22). */
|
|
294
|
+
export const TierPriceSchema = z
|
|
295
|
+
.object({
|
|
296
|
+
/** Price per 1,000,000 input tokens. */
|
|
297
|
+
input: z.number().nonnegative(),
|
|
298
|
+
/** Price per 1,000,000 output tokens. */
|
|
299
|
+
output: z.number().nonnegative(),
|
|
300
|
+
})
|
|
301
|
+
.strict();
|
|
302
|
+
/**
|
|
303
|
+
* Usage telemetry + cost tracking (C.22): LOCAL usage accounting only — nothing
|
|
304
|
+
* here is ever transmitted. Costs are opt-in and honest: prices are per-TIER and
|
|
305
|
+
* per-million-tokens, configured by the user; with none set, tokens are shown
|
|
306
|
+
* and cost is omitted (cruxy ships no bundled price table). The `prices` keys are
|
|
307
|
+
* the fixed {@link MODEL_TIERS}, so an upstream model name can never appear here
|
|
308
|
+
* (U.8 gag holds by construction) and a mistyped tier is rejected at config load.
|
|
309
|
+
*/
|
|
310
|
+
export const UsageConfigSchema = z
|
|
311
|
+
.object({
|
|
312
|
+
/** Master switch. When false, no usage is collected, persisted, or shown. */
|
|
313
|
+
enabled: z.boolean().default(true),
|
|
314
|
+
/** Currency label to prefix costs with (e.g. "$", "€"). Empty ⇒ no symbol is
|
|
315
|
+
* assumed — a bare number is shown, since the user configured the prices. */
|
|
316
|
+
currency: z.string().default(""),
|
|
317
|
+
/** How many past runs to keep in the store; older ones are pruned oldest-first. */
|
|
318
|
+
retention: z.number().int().positive().default(50),
|
|
319
|
+
/** Per-tier prices. Any tier omitted is simply unpriced (cost omitted for it). */
|
|
320
|
+
prices: z
|
|
321
|
+
.object({
|
|
322
|
+
kavi: TierPriceSchema.optional(),
|
|
323
|
+
vaani: TierPriceSchema.optional(),
|
|
324
|
+
mira: TierPriceSchema.optional(),
|
|
325
|
+
})
|
|
326
|
+
.strict()
|
|
327
|
+
.default({}),
|
|
328
|
+
})
|
|
329
|
+
.strict();
|
|
276
330
|
/** MCP server entry — stdio or URL transport (wired up in a later phase). */
|
|
277
331
|
export const McpServerSchema = z
|
|
278
332
|
.object({
|
|
@@ -298,6 +352,8 @@ export const CruxyConfigSchema = z
|
|
|
298
352
|
sandbox: SandboxConfigSchema.default({}),
|
|
299
353
|
hooks: HooksConfigSchema.default({}),
|
|
300
354
|
routing: RoutingConfigSchema.default({}),
|
|
355
|
+
memory: MemoryConfigSchema.default({}),
|
|
356
|
+
usage: UsageConfigSchema.default({}),
|
|
301
357
|
mcpServers: z.record(z.string(), McpServerSchema).default({}),
|
|
302
358
|
logLevel: z.enum(LOG_LEVELS).default("info"),
|
|
303
359
|
})
|
package/dist/constants.d.ts
CHANGED
|
@@ -30,6 +30,24 @@ export declare const COMMANDS_DIR_NAME = "commands";
|
|
|
30
30
|
/** Per-repo hook-trust record, in the GLOBAL dir only (`~/.cruxy/trust.json`) —
|
|
31
31
|
* never in a repo, so cloning carries no trust (C.19 supply-chain safety). */
|
|
32
32
|
export declare const TRUST_FILE_NAME = "trust.json";
|
|
33
|
+
/**
|
|
34
|
+
* Persistent memory (C.29). Structured entries live under the memory subdir of
|
|
35
|
+
* the project dir (`<cwd>/.cruxy/memory`) and the global dir (`~/.cruxy/memory`),
|
|
36
|
+
* one JSON file per scope — pure data, validated, never eval'd.
|
|
37
|
+
*/
|
|
38
|
+
export declare const MEMORY_DIR_NAME = "memory";
|
|
39
|
+
export declare const MEMORY_FILE_NAME = "entries.json";
|
|
40
|
+
/** Per-repo PROJECT-memory trust record, in the GLOBAL dir only
|
|
41
|
+
* (`~/.cruxy/memory-trust.json`) — its own file, independent of hook trust, so
|
|
42
|
+
* cloning a repo carries zero memory trust (C.29 supply-chain safety). */
|
|
43
|
+
export declare const MEMORY_TRUST_FILE_NAME = "memory-trust.json";
|
|
44
|
+
/**
|
|
45
|
+
* Usage telemetry + cost tracking (C.22). Per-run/per-session usage records live
|
|
46
|
+
* in the GLOBAL dir only (`~/.cruxy/usage/runs.json`), `0600` — LOCAL accounting
|
|
47
|
+
* of your own usage, never transmitted. Pure data, validated, never eval'd.
|
|
48
|
+
*/
|
|
49
|
+
export declare const USAGE_DIR_NAME = "usage";
|
|
50
|
+
export declare const USAGE_FILE_NAME = "runs.json";
|
|
33
51
|
/**
|
|
34
52
|
* Absolute path of the shipped builtin skills directory (`<pkg>/skills`).
|
|
35
53
|
* Anchored the same way as the package.json lookup above: both `dist/` and
|
package/dist/constants.js
CHANGED
|
@@ -50,6 +50,24 @@ export const COMMANDS_DIR_NAME = "commands";
|
|
|
50
50
|
/** Per-repo hook-trust record, in the GLOBAL dir only (`~/.cruxy/trust.json`) —
|
|
51
51
|
* never in a repo, so cloning carries no trust (C.19 supply-chain safety). */
|
|
52
52
|
export const TRUST_FILE_NAME = "trust.json";
|
|
53
|
+
/**
|
|
54
|
+
* Persistent memory (C.29). Structured entries live under the memory subdir of
|
|
55
|
+
* the project dir (`<cwd>/.cruxy/memory`) and the global dir (`~/.cruxy/memory`),
|
|
56
|
+
* one JSON file per scope — pure data, validated, never eval'd.
|
|
57
|
+
*/
|
|
58
|
+
export const MEMORY_DIR_NAME = "memory";
|
|
59
|
+
export const MEMORY_FILE_NAME = "entries.json";
|
|
60
|
+
/** Per-repo PROJECT-memory trust record, in the GLOBAL dir only
|
|
61
|
+
* (`~/.cruxy/memory-trust.json`) — its own file, independent of hook trust, so
|
|
62
|
+
* cloning a repo carries zero memory trust (C.29 supply-chain safety). */
|
|
63
|
+
export const MEMORY_TRUST_FILE_NAME = "memory-trust.json";
|
|
64
|
+
/**
|
|
65
|
+
* Usage telemetry + cost tracking (C.22). Per-run/per-session usage records live
|
|
66
|
+
* in the GLOBAL dir only (`~/.cruxy/usage/runs.json`), `0600` — LOCAL accounting
|
|
67
|
+
* of your own usage, never transmitted. Pure data, validated, never eval'd.
|
|
68
|
+
*/
|
|
69
|
+
export const USAGE_DIR_NAME = "usage";
|
|
70
|
+
export const USAGE_FILE_NAME = "runs.json";
|
|
53
71
|
/**
|
|
54
72
|
* Absolute path of the shipped builtin skills directory (`<pkg>/skills`).
|
|
55
73
|
* Anchored the same way as the package.json lookup above: both `dist/` and
|
|
@@ -136,6 +136,27 @@ export declare function subagentFailed(underlying?: unknown): CruxyError;
|
|
|
136
136
|
* invents a test command — the fix is always to declare one.
|
|
137
137
|
*/
|
|
138
138
|
export declare function testCommandNotFound(): CruxyError;
|
|
139
|
+
/**
|
|
140
|
+
* A memory write was refused because the content matched a known secret shape
|
|
141
|
+
* (C.29). Secrets are NEVER persisted to memory — the fix is to remember a
|
|
142
|
+
* non-secret description, not the secret itself.
|
|
143
|
+
*/
|
|
144
|
+
export declare function memorySecretRefused(kind: string): CruxyError;
|
|
145
|
+
/**
|
|
146
|
+
* A repo's project memory is present but has not been trusted on this machine
|
|
147
|
+
* (C.29). It is never recalled into the model's context silently — a cloned repo
|
|
148
|
+
* cannot inject notes until you review and trust them.
|
|
149
|
+
*/
|
|
150
|
+
export declare function memoryUntrusted(root: string): CruxyError;
|
|
151
|
+
/** A malformed memory entry was rejected (C.29) — excluded, never eval'd. */
|
|
152
|
+
export declare function memoryInvalid(detail: string): CruxyError;
|
|
153
|
+
/**
|
|
154
|
+
* The local usage store (`~/.cruxy/usage/runs.json`) is corrupt or unreadable
|
|
155
|
+
* (C.22). Never fatal: usage accounting is best-effort, so the read is SKIPPED
|
|
156
|
+
* and this is surfaced. The fix is always to reset the file — its only content
|
|
157
|
+
* is your own local usage history, so deleting it loses nothing but history.
|
|
158
|
+
*/
|
|
159
|
+
export declare function usageRead(path: string, reason: string, underlying?: unknown): CruxyError;
|
|
139
160
|
export declare function internal(underlying?: unknown): CruxyError;
|
|
140
161
|
/**
|
|
141
162
|
* Map a known provider/transport error (from `@cruxy/sdk`) to a typed
|
|
@@ -602,6 +602,70 @@ export function testCommandNotFound() {
|
|
|
602
602
|
],
|
|
603
603
|
});
|
|
604
604
|
}
|
|
605
|
+
// ── persistent memory (exit 14) — C.29 ────────────────────────────────────────
|
|
606
|
+
/**
|
|
607
|
+
* A memory write was refused because the content matched a known secret shape
|
|
608
|
+
* (C.29). Secrets are NEVER persisted to memory — the fix is to remember a
|
|
609
|
+
* non-secret description, not the secret itself.
|
|
610
|
+
*/
|
|
611
|
+
export function memorySecretRefused(kind) {
|
|
612
|
+
return new CruxyError({
|
|
613
|
+
code: ErrorCode.MemorySecret,
|
|
614
|
+
title: "refused to save that note — it looks like it contains a secret",
|
|
615
|
+
cause: `the content matched a ${kind}; secrets are never written to memory`,
|
|
616
|
+
nextSteps: [
|
|
617
|
+
"remember a non-secret description instead (e.g. “the deploy key lives in 1Password”, not the key)",
|
|
618
|
+
],
|
|
619
|
+
meta: { kind },
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* A repo's project memory is present but has not been trusted on this machine
|
|
624
|
+
* (C.29). It is never recalled into the model's context silently — a cloned repo
|
|
625
|
+
* cannot inject notes until you review and trust them.
|
|
626
|
+
*/
|
|
627
|
+
export function memoryUntrusted(root) {
|
|
628
|
+
return new CruxyError({
|
|
629
|
+
code: ErrorCode.MemoryUntrusted,
|
|
630
|
+
title: "this project's memory has not been trusted",
|
|
631
|
+
cause: "project memory can arrive with a cloned repo (another author), so it is not recalled until you trust it",
|
|
632
|
+
nextSteps: [
|
|
633
|
+
"review the entries with `cruxy memory list`",
|
|
634
|
+
"then trust them with `cruxy memory trust .` (re-trust is required if they change)",
|
|
635
|
+
],
|
|
636
|
+
meta: { root },
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
/** A malformed memory entry was rejected (C.29) — excluded, never eval'd. */
|
|
640
|
+
export function memoryInvalid(detail) {
|
|
641
|
+
return new CruxyError({
|
|
642
|
+
code: ErrorCode.MemoryInvalid,
|
|
643
|
+
title: "a memory entry is malformed and was excluded",
|
|
644
|
+
cause: detail,
|
|
645
|
+
nextSteps: [
|
|
646
|
+
"inspect the file with `cruxy memory list`, or clear it with `cruxy memory clear`",
|
|
647
|
+
],
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
// ── usage telemetry (exit 2) — C.22 ───────────────────────────────────────────
|
|
651
|
+
/**
|
|
652
|
+
* The local usage store (`~/.cruxy/usage/runs.json`) is corrupt or unreadable
|
|
653
|
+
* (C.22). Never fatal: usage accounting is best-effort, so the read is SKIPPED
|
|
654
|
+
* and this is surfaced. The fix is always to reset the file — its only content
|
|
655
|
+
* is your own local usage history, so deleting it loses nothing but history.
|
|
656
|
+
*/
|
|
657
|
+
export function usageRead(path, reason, underlying) {
|
|
658
|
+
return new CruxyError({
|
|
659
|
+
code: ErrorCode.UsageRead,
|
|
660
|
+
title: "could not read the local usage store",
|
|
661
|
+
cause: reason,
|
|
662
|
+
nextSteps: [
|
|
663
|
+
`delete ${path} to reset it (it holds only your local usage history)`,
|
|
664
|
+
],
|
|
665
|
+
underlying,
|
|
666
|
+
meta: { path },
|
|
667
|
+
});
|
|
668
|
+
}
|
|
605
669
|
// ── internal (exit 1) ─────────────────────────────────────────────────────────
|
|
606
670
|
export function internal(underlying) {
|
|
607
671
|
return new CruxyError({
|