kodingo-core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +79 -0
  2. package/dist/index.d.ts +14 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +30 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/src/domain/decision/decision-context.d.ts +12 -0
  7. package/dist/src/domain/decision/decision-context.d.ts.map +1 -0
  8. package/dist/src/domain/decision/decision-context.js +3 -0
  9. package/dist/src/domain/decision/decision-context.js.map +1 -0
  10. package/dist/src/domain/decision/decision-errors.d.ts +3 -0
  11. package/dist/src/domain/decision/decision-errors.d.ts.map +1 -0
  12. package/dist/src/domain/decision/decision-errors.js +7 -0
  13. package/dist/src/domain/decision/decision-errors.js.map +1 -0
  14. package/dist/src/domain/decision/decision-event.d.ts +11 -0
  15. package/dist/src/domain/decision/decision-event.d.ts.map +1 -0
  16. package/dist/src/domain/decision/decision-event.js +3 -0
  17. package/dist/src/domain/decision/decision-event.js.map +1 -0
  18. package/dist/src/domain/decision/decision-outcome.d.ts +7 -0
  19. package/dist/src/domain/decision/decision-outcome.d.ts.map +1 -0
  20. package/dist/src/domain/decision/decision-outcome.js +3 -0
  21. package/dist/src/domain/decision/decision-outcome.js.map +1 -0
  22. package/dist/src/domain/decision/decision.d.ts +31 -0
  23. package/dist/src/domain/decision/decision.d.ts.map +1 -0
  24. package/dist/src/domain/decision/decision.js +3 -0
  25. package/dist/src/domain/decision/decision.js.map +1 -0
  26. package/dist/src/domain/memory/memory-events.d.ts +11 -0
  27. package/dist/src/domain/memory/memory-events.d.ts.map +1 -0
  28. package/dist/src/domain/memory/memory-events.js +13 -0
  29. package/dist/src/domain/memory/memory-events.js.map +1 -0
  30. package/dist/src/domain/memory/project-memory.d.ts +167 -0
  31. package/dist/src/domain/memory/project-memory.d.ts.map +1 -0
  32. package/dist/src/domain/memory/project-memory.js +190 -0
  33. package/dist/src/domain/memory/project-memory.js.map +1 -0
  34. package/dist/src/invariants/decision-invariants.d.ts +4 -0
  35. package/dist/src/invariants/decision-invariants.d.ts.map +1 -0
  36. package/dist/src/invariants/decision-invariants.js +16 -0
  37. package/dist/src/invariants/decision-invariants.js.map +1 -0
  38. package/dist/src/lifecycle/decision-lifecycle.d.ts +5 -0
  39. package/dist/src/lifecycle/decision-lifecycle.d.ts.map +1 -0
  40. package/dist/src/lifecycle/decision-lifecycle.js +29 -0
  41. package/dist/src/lifecycle/decision-lifecycle.js.map +1 -0
  42. package/dist/src/ports/agent-port.d.ts +15 -0
  43. package/dist/src/ports/agent-port.d.ts.map +1 -0
  44. package/dist/src/ports/agent-port.js +3 -0
  45. package/dist/src/ports/agent-port.js.map +1 -0
  46. package/dist/src/ports/assertion-port.d.ts +16 -0
  47. package/dist/src/ports/assertion-port.d.ts.map +1 -0
  48. package/dist/src/ports/assertion-port.js +3 -0
  49. package/dist/src/ports/assertion-port.js.map +1 -0
  50. package/dist/src/ports/event-port.d.ts +10 -0
  51. package/dist/src/ports/event-port.d.ts.map +1 -0
  52. package/dist/src/ports/event-port.js +3 -0
  53. package/dist/src/ports/event-port.js.map +1 -0
  54. package/dist/src/ports/memory-port.d.ts +13 -0
  55. package/dist/src/ports/memory-port.d.ts.map +1 -0
  56. package/dist/src/ports/memory-port.js +3 -0
  57. package/dist/src/ports/memory-port.js.map +1 -0
  58. package/package.json +20 -0
package/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # kodingo-core
2
+
3
+ ## Purpose
4
+
5
+ This repository contains the core domain logic of Kodingo.
6
+
7
+ It is responsible for understanding *why* code changes happen by:
8
+ - Processing events
9
+ - Inferring decisions
10
+ - Writing memory
11
+ - Managing confidence
12
+ - Reconciling assertions over time
13
+
14
+ This repository is intentionally interface-agnostic.
15
+
16
+ ---
17
+
18
+ ## What This Repo Owns
19
+
20
+ - Event processing pipelines
21
+ - Decision inference logic
22
+ - Memory lifecycle management
23
+ - Confidence calculation
24
+ - Assertion reconciliation
25
+ - Conflict resolution logic (logical, not Git-level)
26
+
27
+ ---
28
+
29
+ ## What This Repo Does NOT Do
30
+
31
+ - No CLI commands
32
+ - No terminal interaction
33
+ - No Git commands
34
+ - No filesystem watching
35
+ - No authentication UX
36
+ - No billing logic
37
+
38
+ ---
39
+
40
+ ## Core Invariants
41
+
42
+ - Every code change produces memory
43
+ - Decisions may exist without assertions
44
+ - Confidence may be low without human input
45
+ - Silence is treated as data
46
+ - Memory is immutable; confidence and assertions evolve
47
+
48
+ ---
49
+
50
+ ## Dependencies
51
+
52
+ - Depends on `kodingo-schema`
53
+ - Must never depend on `kodingo-cli`
54
+
55
+ ---
56
+
57
+ ## Architecture Notes
58
+
59
+ - Input: normalized events (from CLI or other adapters)
60
+ - Output: structured memories and decisions
61
+ - All side effects are explicit
62
+ - No hidden state
63
+
64
+ ---
65
+
66
+ ## Change Discipline
67
+
68
+ Any logic added here must be:
69
+ - Deterministic
70
+ - Auditable
71
+ - Explainable
72
+
73
+ If it cannot be explained, it does not belong here.
74
+
75
+ ---
76
+
77
+ ## Status
78
+
79
+ Core domain modeling phase.
@@ -0,0 +1,14 @@
1
+ export * from "./src/lifecycle/decision-lifecycle";
2
+ export * from "./src/invariants/decision-invariants";
3
+ export * from "./src/ports/memory-port";
4
+ export * from "./src/ports/assertion-port";
5
+ export * from "./src/ports/agent-port";
6
+ export * from "./src/ports/event-port";
7
+ export * from "./src/domain/memory/project-memory";
8
+ export * from "./src/domain/memory/memory-events";
9
+ export * from "./src/domain/decision/decision-context";
10
+ export * from "./src/domain/decision/decision";
11
+ export * from "./src/domain/decision/decision-outcome";
12
+ export * from "./src/domain/decision/decision-event";
13
+ export * from "./src/domain/decision/decision-errors";
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,oCAAoC,CAAC;AACnD,cAAc,sCAAsC,CAAC;AAErD,cAAc,yBAAyB,CAAC;AACxC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AAEvC,cAAc,oCAAoC,CAAC;AACnD,cAAc,mCAAmC,CAAC;AAElD,cAAc,wCAAwC,CAAC;AACvD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,wCAAwC,CAAC;AACvD,cAAc,sCAAsC,CAAC;AACrD,cAAc,uCAAuC,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./src/lifecycle/decision-lifecycle"), exports);
18
+ __exportStar(require("./src/invariants/decision-invariants"), exports);
19
+ __exportStar(require("./src/ports/memory-port"), exports);
20
+ __exportStar(require("./src/ports/assertion-port"), exports);
21
+ __exportStar(require("./src/ports/agent-port"), exports);
22
+ __exportStar(require("./src/ports/event-port"), exports);
23
+ __exportStar(require("./src/domain/memory/project-memory"), exports);
24
+ __exportStar(require("./src/domain/memory/memory-events"), exports);
25
+ __exportStar(require("./src/domain/decision/decision-context"), exports);
26
+ __exportStar(require("./src/domain/decision/decision"), exports);
27
+ __exportStar(require("./src/domain/decision/decision-outcome"), exports);
28
+ __exportStar(require("./src/domain/decision/decision-event"), exports);
29
+ __exportStar(require("./src/domain/decision/decision-errors"), exports);
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qEAAmD;AACnD,uEAAqD;AAErD,0DAAwC;AACxC,6DAA2C;AAC3C,yDAAuC;AACvC,yDAAuC;AAEvC,qEAAmD;AACnD,oEAAkD;AAElD,yEAAuD;AACvD,iEAA+C;AAC/C,yEAAuD;AACvD,uEAAqD;AACrD,wEAAsD"}
@@ -0,0 +1,12 @@
1
+ import { ProjectMemory } from "../memory/project-memory";
2
+ export interface DecisionContext {
3
+ /**
4
+ * Memory BEFORE this decision.
5
+ */
6
+ priorMemory: ProjectMemory;
7
+ /**
8
+ * Is this decision human-triggered or system-inferred?
9
+ */
10
+ source: "human" | "system";
11
+ }
12
+ //# sourceMappingURL=decision-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision-context.d.ts","sourceRoot":"","sources":["../../../../src/domain/decision/decision-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,WAAW,EAAE,aAAa,CAAC;IAE3B;;OAEG;IACH,MAAM,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC5B"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=decision-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision-context.js","sourceRoot":"","sources":["../../../../src/domain/decision/decision-context.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ export declare class DecisionInvariantError extends Error {
2
+ }
3
+ //# sourceMappingURL=decision-errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision-errors.d.ts","sourceRoot":"","sources":["../../../../src/domain/decision/decision-errors.ts"],"names":[],"mappings":"AAAA,qBAAa,sBAAuB,SAAQ,KAAK;CAAG"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DecisionInvariantError = void 0;
4
+ class DecisionInvariantError extends Error {
5
+ }
6
+ exports.DecisionInvariantError = DecisionInvariantError;
7
+ //# sourceMappingURL=decision-errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision-errors.js","sourceRoot":"","sources":["../../../../src/domain/decision/decision-errors.ts"],"names":[],"mappings":";;;AAAA,MAAa,sBAAuB,SAAQ,KAAK;CAAG;AAApD,wDAAoD"}
@@ -0,0 +1,11 @@
1
+ import { DecisionId } from "./decision";
2
+ export type DecisionEvent = {
3
+ type: "DecisionRecorded";
4
+ decisionId: DecisionId;
5
+ occurredAt: Date;
6
+ } | {
7
+ type: "MemoryUpdated";
8
+ decisionId: DecisionId;
9
+ occurredAt: Date;
10
+ };
11
+ //# sourceMappingURL=decision-event.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision-event.d.ts","sourceRoot":"","sources":["../../../../src/domain/decision/decision-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,MAAM,aAAa,GACrB;IACE,IAAI,EAAE,kBAAkB,CAAC;IACzB,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,EAAE,IAAI,CAAC;CAClB,GACD;IACE,IAAI,EAAE,eAAe,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,EAAE,IAAI,CAAC;CAClB,CAAC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=decision-event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision-event.js","sourceRoot":"","sources":["../../../../src/domain/decision/decision-event.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ import { ProjectMemory } from "../memory/project-memory";
2
+ import { DecisionEvent } from "./decision-event";
3
+ export interface DecisionOutcome {
4
+ newMemory: ProjectMemory;
5
+ events: DecisionEvent[];
6
+ }
7
+ //# sourceMappingURL=decision-outcome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision-outcome.d.ts","sourceRoot":"","sources":["../../../../src/domain/decision/decision-outcome.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,aAAa,CAAC;IACzB,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=decision-outcome.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision-outcome.js","sourceRoot":"","sources":["../../../../src/domain/decision/decision-outcome.ts"],"names":[],"mappings":""}
@@ -0,0 +1,31 @@
1
+ export type DecisionId = string;
2
+ export type ProjectId = string;
3
+ export interface Decision {
4
+ id: DecisionId;
5
+ projectId: ProjectId;
6
+ /**
7
+ * Human-readable reason for this decision.
8
+ * Must always exist, even if confidence is low.
9
+ */
10
+ rationale: string;
11
+ /**
12
+ * What changed in the code or structure.
13
+ * This is descriptive, not interpretive.
14
+ */
15
+ changeSummary: string;
16
+ /**
17
+ * Optional explicit assertion.
18
+ * Absence does NOT mean absence of memory.
19
+ */
20
+ assertion?: string;
21
+ /**
22
+ * Confidence in the interpretation of the decision.
23
+ * 0.0 – 1.0
24
+ */
25
+ confidence: number;
26
+ /**
27
+ * Timestamp when the decision was proposed.
28
+ */
29
+ proposedAt: Date;
30
+ }
31
+ //# sourceMappingURL=decision.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision.d.ts","sourceRoot":"","sources":["../../../../src/domain/decision/decision.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC;AAChC,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC;AAE/B,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,UAAU,CAAC;IACf,SAAS,EAAE,SAAS,CAAC;IAErB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,UAAU,EAAE,IAAI,CAAC;CAClB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=decision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision.js","sourceRoot":"","sources":["../../../../src/domain/decision/decision.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Memory domain events.
3
+ *
4
+ * This file currently exists to provide a stable module boundary for memory-related
5
+ * events. It must export at least one symbol so TypeScript treats it as a module.
6
+ *
7
+ * Add concrete event types here as the memory domain evolves.
8
+ */
9
+ export type MemoryEvent = never;
10
+ export declare const MEMORY_EVENTS: {};
11
+ //# sourceMappingURL=memory-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-events.d.ts","sourceRoot":"","sources":["../../../../src/domain/memory/memory-events.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,WAAW,GAAG,KAAK,CAAC;AAEhC,eAAO,MAAM,aAAa,IAAc,CAAC"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ /**
3
+ * Memory domain events.
4
+ *
5
+ * This file currently exists to provide a stable module boundary for memory-related
6
+ * events. It must export at least one symbol so TypeScript treats it as a module.
7
+ *
8
+ * Add concrete event types here as the memory domain evolves.
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.MEMORY_EVENTS = void 0;
12
+ exports.MEMORY_EVENTS = {};
13
+ //# sourceMappingURL=memory-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-events.js","sourceRoot":"","sources":["../../../../src/domain/memory/memory-events.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAIU,QAAA,aAAa,GAAG,EAAW,CAAC"}
@@ -0,0 +1,167 @@
1
+ import { DecisionId } from "../decision/decision";
2
+ /**
3
+ * Lifecycle states for memory records.
4
+ * These must match the domain contract exactly.
5
+ */
6
+ export type MemoryStatus = "proposed" | "affirmed" | "denied" | "ignored";
7
+ /**
8
+ * MVP memory types. (Aligned with current CLI usage.)
9
+ */
10
+ export type MemoryType = "decision" | "note" | "context";
11
+ /**
12
+ * Signal categories used for deterministic confidence updates.
13
+ */
14
+ export type SignalWeightClass = "code_change" | "structural" | "metadata";
15
+ /**
16
+ * A single unit of retained knowledge.
17
+ * Canonical vs non-canonical is derived from `status`:
18
+ * - affirmed => canonical
19
+ * - proposed/ignored/denied => non-canonical
20
+ */
21
+ export interface MemoryRecord {
22
+ id: string;
23
+ projectId: string;
24
+ /**
25
+ * Repo scope identity for this record.
26
+ * MVP: store a stable string (e.g., resolved repo root path or other chosen identity).
27
+ */
28
+ repo: string;
29
+ /**
30
+ * Optional symbol linkage (MVP uses symbol-based linkage; line ranges are out of scope).
31
+ * Example: "function:foo" or "class:Bar" or "module:src/x".
32
+ */
33
+ symbol?: string;
34
+ type: MemoryType;
35
+ title?: string;
36
+ tags: string[];
37
+ content: string;
38
+ status: MemoryStatus;
39
+ confidence: number;
40
+ createdAt: Date;
41
+ updatedAt: Date;
42
+ /**
43
+ * Evidence counters used for saturation/diminishing returns.
44
+ */
45
+ evidence: {
46
+ strongCodeChangeCount: number;
47
+ structuralCount: number;
48
+ metadataCount: number;
49
+ /**
50
+ * Total confidence gained from signals alone (excludes affirmation boosts).
51
+ * Used to cap evidence contribution.
52
+ */
53
+ evidenceGain: number;
54
+ };
55
+ /**
56
+ * If a record was denied, we track when (for anti-loop / history).
57
+ */
58
+ deniedAt?: Date;
59
+ /**
60
+ * Optional fingerprint to help avoid re-proposing the same denied hypothesis.
61
+ * For MVP, leave it as a caller-provided string if available.
62
+ */
63
+ fingerprint?: string;
64
+ /**
65
+ * Stable external identifier for deduplication across signal sources.
66
+ * Example: "git:<commitHash>"
67
+ */
68
+ externalId?: string;
69
+ /**
70
+ * Correction lineage — set when this record is a corrected replacement.
71
+ * Points to the denied record this record supersedes.
72
+ */
73
+ correctsId?: string;
74
+ /**
75
+ * Correction lineage — set on a denied record.
76
+ * Points to the proposed replacement that was created when this was denied.
77
+ */
78
+ correctedById?: string;
79
+ }
80
+ /**
81
+ * Project memory state for a project.
82
+ *
83
+ * Backward compatible:
84
+ * - Existing fields remain unchanged.
85
+ * - New field `memories` is optional for now so existing callers won't break.
86
+ */
87
+ export interface ProjectMemory {
88
+ projectId: string;
89
+ /**
90
+ * Ordered list of decisions that define the project.
91
+ */
92
+ decisions: DecisionId[];
93
+ /**
94
+ * Optional memory records store.
95
+ * (MVP: used by CLI/IDE surfaces; can remain empty if not yet integrated.)
96
+ */
97
+ memories?: MemoryRecord[];
98
+ /**
99
+ * Last updated timestamp.
100
+ */
101
+ updatedAt: Date;
102
+ }
103
+ export declare function isCanonical(status: MemoryStatus): boolean;
104
+ export declare function createProposedMemory(input: {
105
+ id: string;
106
+ projectId: string;
107
+ repo: string;
108
+ type: MemoryType;
109
+ content: string;
110
+ title?: string;
111
+ tags?: string[];
112
+ symbol?: string;
113
+ fingerprint?: string;
114
+ externalId?: string;
115
+ correctsId?: string;
116
+ now?: Date;
117
+ }): MemoryRecord;
118
+ /**
119
+ * Apply a signal to a memory record.
120
+ * This increases confidence deterministically, with saturation + diminishing returns.
121
+ *
122
+ * NOTE: Signals can also raise confidence for ignored records (non-canonical),
123
+ * but never make them canonical automatically.
124
+ */
125
+ export declare function applySignal(record: MemoryRecord, signal: {
126
+ weightClass: SignalWeightClass;
127
+ now?: Date;
128
+ }): MemoryRecord;
129
+ /**
130
+ * Transition a record to affirmed (canonical) and apply affirmation boosts.
131
+ */
132
+ export declare function affirm(record: MemoryRecord, now?: Date): MemoryRecord;
133
+ /**
134
+ * Transition a record to ignored (non-canonical).
135
+ * Ignore is not rejection; confidence is not forced down.
136
+ */
137
+ export declare function ignore(record: MemoryRecord, now?: Date): MemoryRecord;
138
+ /**
139
+ * Transition a record to denied (non-canonical) and clamp confidence.
140
+ * Denied records are retained to prevent proposal loops.
141
+ */
142
+ export declare function deny(record: MemoryRecord, now?: Date): MemoryRecord;
143
+ /**
144
+ * Select the best record to surface by default for a given target.
145
+ *
146
+ * Default hierarchy:
147
+ * 1) affirmed + highest confidence
148
+ * 2) affirmed + most recent
149
+ * 3) otherwise proposed/ignored (highest confidence, most recent)
150
+ * Denied records are never selected by default.
151
+ */
152
+ export declare function selectDefaultSurfaceRecord(records: ReadonlyArray<MemoryRecord>): MemoryRecord | undefined;
153
+ /**
154
+ * Anti-loop helper:
155
+ * returns true if a denied record exists that should block re-proposing,
156
+ * unless new evidence threshold is met.
157
+ *
158
+ * MVP rule:
159
+ * - If there is a denied record for same target+fingerprint, do not re-propose unless
160
+ * at least 3 strong code-change signals have occurred since denial.
161
+ */
162
+ export declare function shouldBlockReproposal(params: {
163
+ deniedRecord: MemoryRecord;
164
+ strongSignalsSinceDenial: number;
165
+ fingerprint?: string;
166
+ }): boolean;
167
+ //# sourceMappingURL=project-memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-memory.d.ts","sourceRoot":"","sources":["../../../../src/domain/memory/project-memory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isCanonical = isCanonical;
4
+ exports.createProposedMemory = createProposedMemory;
5
+ exports.applySignal = applySignal;
6
+ exports.affirm = affirm;
7
+ exports.ignore = ignore;
8
+ exports.deny = deny;
9
+ exports.selectDefaultSurfaceRecord = selectDefaultSurfaceRecord;
10
+ exports.shouldBlockReproposal = shouldBlockReproposal;
11
+ /* =========================================================
12
+ Confidence + lifecycle rules (domain contract enforcement)
13
+ ========================================================= */
14
+ const clamp01 = (n) => Math.max(0, Math.min(1, n));
15
+ const BASE_CONFIDENCE = {
16
+ proposed: 0.3,
17
+ ignored: 0.3,
18
+ affirmed: 0.8,
19
+ denied: 0.2,
20
+ };
21
+ const SIGNAL_WEIGHT = {
22
+ code_change: 0.06,
23
+ structural: 0.04,
24
+ metadata: 0.01,
25
+ };
26
+ const EVIDENCE_GAIN_CAP = 0.35;
27
+ const STRONG_SIGNAL_DIMINISH_AFTER = 5;
28
+ const STRONG_SIGNAL_DIMINISHED_WEIGHT = 0.03;
29
+ function isCanonical(status) {
30
+ return status === "affirmed";
31
+ }
32
+ function createProposedMemory(input) {
33
+ const now = input.now ?? new Date();
34
+ return {
35
+ id: input.id,
36
+ projectId: input.projectId,
37
+ repo: input.repo,
38
+ symbol: input.symbol,
39
+ type: input.type,
40
+ title: input.title,
41
+ tags: input.tags ?? [],
42
+ content: input.content,
43
+ status: "proposed",
44
+ confidence: BASE_CONFIDENCE.proposed,
45
+ createdAt: now,
46
+ updatedAt: now,
47
+ evidence: {
48
+ strongCodeChangeCount: 0,
49
+ structuralCount: 0,
50
+ metadataCount: 0,
51
+ evidenceGain: 0,
52
+ },
53
+ fingerprint: input.fingerprint,
54
+ externalId: input.externalId,
55
+ correctsId: input.correctsId,
56
+ };
57
+ }
58
+ /**
59
+ * Apply a signal to a memory record.
60
+ * This increases confidence deterministically, with saturation + diminishing returns.
61
+ *
62
+ * NOTE: Signals can also raise confidence for ignored records (non-canonical),
63
+ * but never make them canonical automatically.
64
+ */
65
+ function applySignal(record, signal) {
66
+ const now = signal.now ?? new Date();
67
+ const baseWeight = SIGNAL_WEIGHT[signal.weightClass];
68
+ let weight = baseWeight;
69
+ // Diminishing returns for strong signals after N.
70
+ if (signal.weightClass === "code_change") {
71
+ const nextStrongCount = record.evidence.strongCodeChangeCount + 1;
72
+ if (nextStrongCount > STRONG_SIGNAL_DIMINISH_AFTER) {
73
+ weight = STRONG_SIGNAL_DIMINISHED_WEIGHT;
74
+ }
75
+ }
76
+ // Enforce evidence gain cap (signals alone cannot increase beyond cap).
77
+ const remaining = EVIDENCE_GAIN_CAP - record.evidence.evidenceGain;
78
+ const delta = Math.max(0, Math.min(weight, remaining));
79
+ const nextEvidence = { ...record.evidence };
80
+ if (signal.weightClass === "code_change")
81
+ nextEvidence.strongCodeChangeCount += 1;
82
+ if (signal.weightClass === "structural")
83
+ nextEvidence.structuralCount += 1;
84
+ if (signal.weightClass === "metadata")
85
+ nextEvidence.metadataCount += 1;
86
+ nextEvidence.evidenceGain = clamp01(nextEvidence.evidenceGain + delta);
87
+ let nextConfidence = clamp01(record.confidence + delta);
88
+ // Denied hypotheses remain low-confidence.
89
+ if (record.status === "denied") {
90
+ nextConfidence = Math.min(nextConfidence, BASE_CONFIDENCE.denied);
91
+ }
92
+ return {
93
+ ...record,
94
+ evidence: nextEvidence,
95
+ confidence: nextConfidence,
96
+ updatedAt: now,
97
+ };
98
+ }
99
+ /**
100
+ * Transition a record to affirmed (canonical) and apply affirmation boosts.
101
+ */
102
+ function affirm(record, now = new Date()) {
103
+ let nextConfidence = record.confidence;
104
+ if (record.status !== "affirmed") {
105
+ nextConfidence = Math.max(nextConfidence, BASE_CONFIDENCE.affirmed);
106
+ nextConfidence = clamp01(nextConfidence + 0.1);
107
+ }
108
+ else {
109
+ nextConfidence = clamp01(nextConfidence + 0.05);
110
+ }
111
+ return {
112
+ ...record,
113
+ status: "affirmed",
114
+ confidence: nextConfidence,
115
+ deniedAt: undefined,
116
+ updatedAt: now,
117
+ };
118
+ }
119
+ /**
120
+ * Transition a record to ignored (non-canonical).
121
+ * Ignore is not rejection; confidence is not forced down.
122
+ */
123
+ function ignore(record, now = new Date()) {
124
+ return {
125
+ ...record,
126
+ status: "ignored",
127
+ updatedAt: now,
128
+ };
129
+ }
130
+ /**
131
+ * Transition a record to denied (non-canonical) and clamp confidence.
132
+ * Denied records are retained to prevent proposal loops.
133
+ */
134
+ function deny(record, now = new Date()) {
135
+ return {
136
+ ...record,
137
+ status: "denied",
138
+ confidence: Math.min(record.confidence, BASE_CONFIDENCE.denied),
139
+ deniedAt: now,
140
+ updatedAt: now,
141
+ };
142
+ }
143
+ /**
144
+ * Select the best record to surface by default for a given target.
145
+ *
146
+ * Default hierarchy:
147
+ * 1) affirmed + highest confidence
148
+ * 2) affirmed + most recent
149
+ * 3) otherwise proposed/ignored (highest confidence, most recent)
150
+ * Denied records are never selected by default.
151
+ */
152
+ function selectDefaultSurfaceRecord(records) {
153
+ const affirmed = records.filter((r) => r.status === "affirmed");
154
+ if (affirmed.length > 0) {
155
+ return affirmed.slice().sort((a, b) => {
156
+ if (b.confidence !== a.confidence)
157
+ return b.confidence - a.confidence;
158
+ return b.updatedAt.getTime() - a.updatedAt.getTime();
159
+ })[0];
160
+ }
161
+ const candidates = records.filter((r) => r.status === "proposed" || r.status === "ignored");
162
+ if (candidates.length === 0)
163
+ return undefined;
164
+ return candidates.slice().sort((a, b) => {
165
+ if (b.confidence !== a.confidence)
166
+ return b.confidence - a.confidence;
167
+ return b.updatedAt.getTime() - a.updatedAt.getTime();
168
+ })[0];
169
+ }
170
+ /**
171
+ * Anti-loop helper:
172
+ * returns true if a denied record exists that should block re-proposing,
173
+ * unless new evidence threshold is met.
174
+ *
175
+ * MVP rule:
176
+ * - If there is a denied record for same target+fingerprint, do not re-propose unless
177
+ * at least 3 strong code-change signals have occurred since denial.
178
+ */
179
+ function shouldBlockReproposal(params) {
180
+ const { deniedRecord, strongSignalsSinceDenial, fingerprint } = params;
181
+ if (deniedRecord.status !== "denied")
182
+ return false;
183
+ if (fingerprint &&
184
+ deniedRecord.fingerprint &&
185
+ fingerprint !== deniedRecord.fingerprint) {
186
+ return false;
187
+ }
188
+ return strongSignalsSinceDenial < 3;
189
+ }
190
+ //# sourceMappingURL=project-memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-memory.js","sourceRoot":"","sources":["../../../../src/domain/memory/project-memory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { Decision } from "../domain/decision/decision";
2
+ import { DecisionContext } from "../domain/decision/decision-context";
3
+ export declare function enforceDecisionInvariants(decision: Decision, context: DecisionContext): void;
4
+ //# sourceMappingURL=decision-invariants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision-invariants.d.ts","sourceRoot":"","sources":["../../../src/invariants/decision-invariants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAGtE,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,eAAe,QAazB"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.enforceDecisionInvariants = enforceDecisionInvariants;
4
+ const decision_errors_1 = require("../domain/decision/decision-errors");
5
+ function enforceDecisionInvariants(decision, context) {
6
+ if (decision.projectId !== context.priorMemory.projectId) {
7
+ throw new decision_errors_1.DecisionInvariantError("Decision project mismatch");
8
+ }
9
+ if (!decision.rationale || decision.rationale.trim() === "") {
10
+ throw new decision_errors_1.DecisionInvariantError("Decision must have a rationale");
11
+ }
12
+ if (decision.confidence < 0 || decision.confidence > 1) {
13
+ throw new decision_errors_1.DecisionInvariantError("Invalid confidence score");
14
+ }
15
+ }
16
+ //# sourceMappingURL=decision-invariants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision-invariants.js","sourceRoot":"","sources":["../../../src/invariants/decision-invariants.ts"],"names":[],"mappings":";;AAIA,8DAeC;AAjBD,wEAA4E;AAE5E,SAAgB,yBAAyB,CACvC,QAAkB,EAClB,OAAwB;IAExB,IAAI,QAAQ,CAAC,SAAS,KAAK,OAAO,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC;QACzD,MAAM,IAAI,wCAAsB,CAAC,2BAA2B,CAAC,CAAC;IAChE,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,SAAS,IAAI,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC5D,MAAM,IAAI,wCAAsB,CAAC,gCAAgC,CAAC,CAAC;IACrE,CAAC;IAED,IAAI,QAAQ,CAAC,UAAU,GAAG,CAAC,IAAI,QAAQ,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,wCAAsB,CAAC,0BAA0B,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { Decision } from "../domain/decision/decision";
2
+ import { DecisionContext } from "../domain/decision/decision-context";
3
+ import { DecisionOutcome } from "../domain/decision/decision-outcome";
4
+ export declare function applyDecisionLifecycle(decision: Decision, context: DecisionContext): DecisionOutcome;
5
+ //# sourceMappingURL=decision-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision-lifecycle.d.ts","sourceRoot":"","sources":["../../../src/lifecycle/decision-lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAGtE,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,eAAe,GACvB,eAAe,CA0BjB"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.applyDecisionLifecycle = applyDecisionLifecycle;
4
+ const decision_invariants_1 = require("../invariants/decision-invariants");
5
+ function applyDecisionLifecycle(decision, context) {
6
+ // 1. Enforce invariants
7
+ (0, decision_invariants_1.enforceDecisionInvariants)(decision, context);
8
+ // 2. Produce events
9
+ const events = [
10
+ {
11
+ type: "DecisionRecorded",
12
+ decisionId: decision.id,
13
+ occurredAt: new Date(),
14
+ },
15
+ {
16
+ type: "MemoryUpdated",
17
+ decisionId: decision.id,
18
+ occurredAt: new Date(),
19
+ },
20
+ ];
21
+ // 3. Apply to memory (pure)
22
+ const newMemory = {
23
+ ...context.priorMemory,
24
+ decisions: [...context.priorMemory.decisions, decision.id],
25
+ updatedAt: new Date(),
26
+ };
27
+ return { newMemory, events };
28
+ }
29
+ //# sourceMappingURL=decision-lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision-lifecycle.js","sourceRoot":"","sources":["../../../src/lifecycle/decision-lifecycle.ts"],"names":[],"mappings":";;AAKA,wDA6BC;AA/BD,2EAA8E;AAE9E,SAAgB,sBAAsB,CACpC,QAAkB,EAClB,OAAwB;IAExB,wBAAwB;IACxB,IAAA,+CAAyB,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAE7C,oBAAoB;IACpB,MAAM,MAAM,GAAG;QACb;YACE,IAAI,EAAE,kBAA2B;YACjC,UAAU,EAAE,QAAQ,CAAC,EAAE;YACvB,UAAU,EAAE,IAAI,IAAI,EAAE;SACvB;QACD;YACE,IAAI,EAAE,eAAwB;YAC9B,UAAU,EAAE,QAAQ,CAAC,EAAE;YACvB,UAAU,EAAE,IAAI,IAAI,EAAE;SACvB;KACF,CAAC;IAEF,4BAA4B;IAC5B,MAAM,SAAS,GAAG;QAChB,GAAG,OAAO,CAAC,WAAW;QACtB,SAAS,EAAE,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,CAAC;QAC1D,SAAS,EAAE,IAAI,IAAI,EAAE;KACtB,CAAC;IAEF,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { Decision } from "../domain/decision/decision";
2
+ import { DecisionContext } from "../domain/decision/decision-context";
3
+ import { DecisionOutcome } from "../domain/decision/decision-outcome";
4
+ export interface AgentPort {
5
+ /**
6
+ * External AI agent proposes a new decision.
7
+ * Core will validate and return the outcome.
8
+ */
9
+ proposeDecision(decision: Decision, context: DecisionContext): Promise<DecisionOutcome>;
10
+ /**
11
+ * Query the current state of project memory.
12
+ */
13
+ queryMemory(projectId: string): Promise<any>;
14
+ }
15
+ //# sourceMappingURL=agent-port.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-port.d.ts","sourceRoot":"","sources":["../../../src/ports/agent-port.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAEtE,MAAM,WAAW,SAAS;IACxB;;;OAGG;IACH,eAAe,CACb,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,eAAe,CAAC,CAAC;IAE5B;;OAEG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CAC9C"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=agent-port.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-port.js","sourceRoot":"","sources":["../../../src/ports/agent-port.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ export interface AssertionPort {
2
+ /**
3
+ * Apply an assertion (human or AI) to a decision.
4
+ * Returns updated confidence for that decision.
5
+ */
6
+ submitAssertion(decisionId: string, assertion: string, source: "human" | "system"): Promise<number>;
7
+ /**
8
+ * Optionally query all assertions associated with a decision.
9
+ */
10
+ getAssertions(decisionId: string): Promise<{
11
+ assertion: string;
12
+ source: string;
13
+ createdAt: Date;
14
+ }[]>;
15
+ }
16
+ //# sourceMappingURL=assertion-port.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertion-port.d.ts","sourceRoot":"","sources":["../../../src/ports/assertion-port.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,eAAe,CACb,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,OAAO,GAAG,QAAQ,GACzB,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnB;;OAEG;IACH,aAAa,CACX,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,IAAI,CAAA;KAAE,EAAE,CAAC,CAAC;CACtE"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=assertion-port.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertion-port.js","sourceRoot":"","sources":["../../../src/ports/assertion-port.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ import { Decision } from "../domain/decision/decision";
2
+ import { DecisionContext } from "../domain/decision/decision-context";
3
+ export interface EventPort {
4
+ /**
5
+ * Push a proposed decision into the core.
6
+ * Core will validate invariants and produce a DecisionOutcome.
7
+ */
8
+ pushDecision(decision: Decision, context: DecisionContext): Promise<void>;
9
+ }
10
+ //# sourceMappingURL=event-port.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-port.d.ts","sourceRoot":"","sources":["../../../src/ports/event-port.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAEtE,MAAM,WAAW,SAAS;IACxB;;;OAGG;IACH,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3E"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=event-port.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-port.js","sourceRoot":"","sources":["../../../src/ports/event-port.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ import { DecisionOutcome } from "../domain/decision/decision-outcome";
2
+ export interface MemoryPort {
3
+ /**
4
+ * Persist the updated project memory and associated events.
5
+ * Core will produce DecisionOutcome that this port stores.
6
+ */
7
+ persistMemory(outcome: DecisionOutcome): Promise<void>;
8
+ /**
9
+ * Retrieve the current state of project memory for a given project.
10
+ */
11
+ getMemory(projectId: string): Promise<any>;
12
+ }
13
+ //# sourceMappingURL=memory-port.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-port.d.ts","sourceRoot":"","sources":["../../../src/ports/memory-port.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAEtE,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvD;;OAEG;IACH,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CAC5C"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=memory-port.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-port.js","sourceRoot":"","sources":["../../../src/ports/memory-port.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "kodingo-core",
3
+ "version": "0.1.0",
4
+ "description": "Core domain logic and ports for Kodingo.",
5
+ "license": "ISC",
6
+ "type": "commonjs",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "scripts": {
13
+ "clean": "rm -rf dist",
14
+ "build": "tsc -p tsconfig.json",
15
+ "prepare": "npm run build"
16
+ },
17
+ "devDependencies": {
18
+ "typescript": "^5.3.3"
19
+ }
20
+ }