@feltdb/core 0.6.9 → 0.6.11

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 (122) hide show
  1. package/dist/cli/application-lifecycle.js +112 -0
  2. package/dist/cli/application.js +10 -0
  3. package/dist/cli/commands.js +407 -119
  4. package/dist/cli/development-session.js +54 -0
  5. package/dist/cli/index.js +1 -1
  6. package/dist/cli/workspace-integration.js +146 -20
  7. package/dist/collection.d.ts +110 -2
  8. package/dist/collection.d.ts.map +1 -1
  9. package/dist/collection.js +228 -3
  10. package/dist/create/cli.js +4 -2
  11. package/dist/create/create.js +42 -6
  12. package/dist/create/frameworks.js +18 -0
  13. package/dist/create/package-versions.js +1 -1
  14. package/dist/create/server-source/crates/feltdb/src/bin/feltdb_node.rs +408 -178
  15. package/dist/create/server-source/crates/feltdb/src/lib.rs +49 -5
  16. package/dist/create/server-source/crates/feltdb/src/multi_operation_transaction.rs +659 -0
  17. package/dist/create/server-source/crates/feltdb/src/p1_application_atomicity.rs +285 -0
  18. package/dist/create/server-source/crates/feltdb/src/p1_atomicity_acceptance.rs +582 -0
  19. package/dist/create/server-source/crates/feltdb-server/src/main.rs +141 -0
  20. package/dist/create/workspace-initialization.js +4 -5
  21. package/dist/db.d.ts +63 -1
  22. package/dist/db.d.ts.map +1 -1
  23. package/dist/db.js +145 -4
  24. package/dist/development-runtime-bridge.d.ts +60 -0
  25. package/dist/development-runtime-bridge.d.ts.map +1 -0
  26. package/dist/development-runtime-bridge.js +171 -0
  27. package/dist/embedded-transaction.d.ts +77 -0
  28. package/dist/embedded-transaction.d.ts.map +1 -0
  29. package/dist/embedded-transaction.js +102 -0
  30. package/dist/feltdb.d.ts +49 -1
  31. package/dist/feltdb.d.ts.map +1 -1
  32. package/dist/file-db.d.ts +33 -0
  33. package/dist/file-db.d.ts.map +1 -1
  34. package/dist/file-db.js +128 -4
  35. package/dist/freshness.d.ts +119 -0
  36. package/dist/freshness.d.ts.map +1 -0
  37. package/dist/freshness.js +115 -0
  38. package/dist/http-db.d.ts +48 -0
  39. package/dist/http-db.d.ts.map +1 -1
  40. package/dist/http-db.js +77 -1
  41. package/dist/index-backend.d.ts +8 -0
  42. package/dist/index-backend.d.ts.map +1 -1
  43. package/dist/index-backend.js +13 -0
  44. package/dist/index-core.d.ts +80 -0
  45. package/dist/index-core.d.ts.map +1 -0
  46. package/dist/index-core.js +74 -0
  47. package/dist/index-manager.d.ts +11 -0
  48. package/dist/index-manager.d.ts.map +1 -1
  49. package/dist/index-manager.js +30 -13
  50. package/dist/index-types.d.ts +17 -0
  51. package/dist/index-types.d.ts.map +1 -1
  52. package/dist/index.browser.d.ts +14 -0
  53. package/dist/index.browser.d.ts.map +1 -0
  54. package/dist/index.browser.js +13 -0
  55. package/dist/index.d.ts +8 -59
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +11 -54
  58. package/dist/indexeddb-db.d.ts +32 -0
  59. package/dist/indexeddb-db.d.ts.map +1 -1
  60. package/dist/indexeddb-db.js +151 -1
  61. package/dist/memory-db.d.ts +26 -0
  62. package/dist/memory-db.d.ts.map +1 -1
  63. package/dist/memory-db.js +86 -0
  64. package/dist/runtime-registry.d.ts +32 -0
  65. package/dist/runtime-registry.d.ts.map +1 -0
  66. package/dist/runtime-registry.js +38 -0
  67. package/dist/studio/app.d.ts +2 -1
  68. package/dist/studio/app.d.ts.map +1 -1
  69. package/dist/studio/components/StateExplorer.d.ts +2 -1
  70. package/dist/studio/components/StateExplorer.d.ts.map +1 -1
  71. package/dist/studio/components/index.js +1 -1
  72. package/dist/studio/{components-9kDSWiGL.js → components-C5p2TfIU.js} +25 -14
  73. package/dist/studio/index.js +234 -160
  74. package/dist/studio-app/assets/{feltdb_wasm-B4wq4mqp.js → feltdb_wasm-CJv3wHzi.js} +1 -1
  75. package/dist/studio-app/assets/feltdb_wasm_bg-C8TG8r2n.wasm +0 -0
  76. package/dist/studio-app/assets/index-DospFFYE.js +28 -0
  77. package/dist/studio-app/index.html +1 -1
  78. package/dist/transaction.d.ts +98 -0
  79. package/dist/transaction.d.ts.map +1 -0
  80. package/dist/transaction.js +86 -0
  81. package/dist/wasm/feltdb_wasm_bg.wasm +0 -0
  82. package/dist/workspace/browser.d.ts +22 -0
  83. package/dist/workspace/browser.d.ts.map +1 -0
  84. package/dist/workspace/browser.js +17 -0
  85. package/dist/workspace/development-node.d.ts +16 -0
  86. package/dist/workspace/development-node.d.ts.map +1 -1
  87. package/dist/workspace/development-node.js +85 -1
  88. package/dist/workspace/git-identity.d.ts +35 -0
  89. package/dist/workspace/git-identity.d.ts.map +1 -0
  90. package/dist/workspace/git-identity.js +81 -0
  91. package/dist/workspace/index.d.ts +12 -2
  92. package/dist/workspace/index.d.ts.map +1 -1
  93. package/dist/workspace/index.js +7 -1
  94. package/dist/workspace/investigation-analysis.d.ts +47 -0
  95. package/dist/workspace/investigation-analysis.d.ts.map +1 -0
  96. package/dist/workspace/investigation-analysis.js +181 -0
  97. package/dist/workspace/investigation-lifecycle-manager.d.ts +88 -0
  98. package/dist/workspace/investigation-lifecycle-manager.d.ts.map +1 -0
  99. package/dist/workspace/investigation-lifecycle-manager.js +259 -0
  100. package/dist/workspace/investigation-supervisor.d.ts +100 -0
  101. package/dist/workspace/investigation-supervisor.d.ts.map +1 -0
  102. package/dist/workspace/investigation-supervisor.js +238 -0
  103. package/dist/workspace/runtime-investigation.d.ts +5 -1
  104. package/dist/workspace/runtime-investigation.d.ts.map +1 -1
  105. package/dist/workspace/runtime-investigation.js +50 -21
  106. package/dist/workspace/runtime-observation.d.ts +82 -0
  107. package/dist/workspace/runtime-observation.d.ts.map +1 -0
  108. package/dist/workspace/runtime-observation.js +170 -0
  109. package/dist/workspace/runtime-observer.d.ts +57 -0
  110. package/dist/workspace/runtime-observer.d.ts.map +1 -0
  111. package/dist/workspace/runtime-observer.js +272 -0
  112. package/dist/workspace/workspace-connection.d.ts.map +1 -1
  113. package/dist/workspace/workspace-connection.js +14 -5
  114. package/dist/workspace/workspace-identity.d.ts +1 -1
  115. package/dist/workspace/workspace-identity.d.ts.map +1 -1
  116. package/dist/workspace/workspace-identity.js +4 -4
  117. package/dist/workspace/workspace-types.d.ts +208 -0
  118. package/dist/workspace/workspace-types.d.ts.map +1 -1
  119. package/package.json +12 -4
  120. package/dist/create/server-source/crates/feltdb/src/phase_1c_three_node.rs +0 -523
  121. package/dist/studio-app/assets/feltdb_wasm_bg-Ceyi7l21.wasm +0 -0
  122. package/dist/studio-app/assets/index-BF45M757.js +0 -28
@@ -1,3 +1,3 @@
1
- <!doctype html><html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#17211b"/><title>FeltDB Studio</title> <script type="module" crossorigin src="/assets/index-BF45M757.js"></script>
1
+ <!doctype html><html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#17211b"/><title>FeltDB Studio</title> <script type="module" crossorigin src="/assets/index-DospFFYE.js"></script>
2
2
  <link rel="stylesheet" crossorigin href="/assets/index-C1GWyazR.css">
3
3
  </head><body><div id="root"></div></body></html>
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Application-facing multi-operation transactions.
3
+ *
4
+ * ```ts
5
+ * const result = await db.transaction(async tx => {
6
+ * tx.collection('users').set('u1', user);
7
+ * tx.collection('orders').set('o1', order);
8
+ * tx.collection('audit').set('a1', event);
9
+ * });
10
+ * ```
11
+ *
12
+ * Either every operation commits or none do.
13
+ *
14
+ * The callback **stages** operations; it does not write them. Nothing reaches
15
+ * the authority until the callback returns, at which point the whole
16
+ * transaction is sent as one request and committed as one durable record. That
17
+ * is what makes the guarantee real: there is no window in which some of the
18
+ * operations have been written and others have not.
19
+ *
20
+ * FeltDB does not implement a second transaction mechanism in TypeScript. This
21
+ * builder produces a request for the store's own atomic transaction path, and
22
+ * a runtime that cannot provide that path refuses the transaction rather than
23
+ * silently degrading it into a sequence of independent writes.
24
+ */
25
+ /** One staged operation. An absent value means delete. */
26
+ export interface AtomicTransactionOperationRequest {
27
+ collection: string;
28
+ id: string;
29
+ value?: Record<string, unknown>;
30
+ /** When set, the record must not already exist for the transaction to commit. */
31
+ requireAbsent?: boolean;
32
+ }
33
+ export interface AtomicTransactionRequest {
34
+ transactionId: string;
35
+ operations: AtomicTransactionOperationRequest[];
36
+ }
37
+ export interface AtomicTransactionResult {
38
+ /** Durable identity of the transaction. Stable across restart and replay. */
39
+ transactionId: string;
40
+ /** True when this id was already committed; nothing was applied again. */
41
+ duplicate: boolean;
42
+ operations: number;
43
+ stateBefore: number;
44
+ stateAfter: number;
45
+ }
46
+ /** Staging surface for one collection inside a transaction. */
47
+ export interface AtomicTransactionCollection<T = unknown> {
48
+ /** Stage a write. */
49
+ set(id: string | number, value: T, options?: {
50
+ requireAbsent?: boolean;
51
+ }): AtomicTransactionCollection<T>;
52
+ /**
53
+ * Stage a write, in the argument order used by `Collection.insert`.
54
+ *
55
+ * Identical to `set` with the arguments swapped, so code that reads like the
56
+ * rest of the collection API does not have to change shape inside a
57
+ * transaction.
58
+ */
59
+ insert(value: T, id: string | number, options?: {
60
+ requireAbsent?: boolean;
61
+ }): AtomicTransactionCollection<T>;
62
+ /** Stage a delete. */
63
+ delete(id: string | number, options?: {
64
+ requireAbsent?: boolean;
65
+ }): AtomicTransactionCollection<T>;
66
+ }
67
+ /** The handle passed to a transaction callback. */
68
+ export interface AtomicTransactionScope {
69
+ /** The transaction's durable identity, available while staging. */
70
+ readonly transactionId: string;
71
+ collection<T = unknown>(name: string): AtomicTransactionCollection<T>;
72
+ /** Operations staged so far. */
73
+ readonly operations: readonly AtomicTransactionOperationRequest[];
74
+ }
75
+ export interface AtomicTransactionOptions {
76
+ /**
77
+ * Supply an identity to make the commit idempotent: retrying with the same
78
+ * id after an uncertain outcome cannot apply the transaction twice.
79
+ */
80
+ transactionId?: string;
81
+ }
82
+ /** Thrown when a transaction cannot be committed. Nothing was applied. */
83
+ export declare class AtomicTransactionError extends Error {
84
+ readonly transactionId: string;
85
+ constructor(message: string, transactionId: string);
86
+ }
87
+ /** Collects operations without performing any I/O. */
88
+ export declare class AtomicTransactionBuilder implements AtomicTransactionScope {
89
+ readonly transactionId: string;
90
+ private readonly staged;
91
+ private sealed;
92
+ constructor(transactionId?: string);
93
+ get operations(): readonly AtomicTransactionOperationRequest[];
94
+ collection<T = unknown>(name: string): AtomicTransactionCollection<T>;
95
+ /** Freeze the builder and produce the request to send. */
96
+ seal(): AtomicTransactionRequest;
97
+ }
98
+ //# sourceMappingURL=transaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../src/transaction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,0DAA0D;AAC1D,MAAM,WAAW,iCAAiC;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,iFAAiF;IACjF,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,iCAAiC,EAAE,CAAC;CACjD;AAED,MAAM,WAAW,uBAAuB;IACtC,6EAA6E;IAC7E,aAAa,EAAE,MAAM,CAAC;IACtB,0EAA0E;IAC1E,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,+DAA+D;AAC/D,MAAM,WAAW,2BAA2B,CAAC,CAAC,GAAG,OAAO;IACtD,qBAAqB;IACrB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,2BAA2B,CAAC,CAAC,CAAC,CAAC;IAC1G;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,2BAA2B,CAAC,CAAC,CAAC,CAAC;IAC7G,sBAAsB;IACtB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,2BAA2B,CAAC,CAAC,CAAC,CAAC;CACpG;AAED,mDAAmD;AACnD,MAAM,WAAW,sBAAsB;IACrC,mEAAmE;IACnE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,2BAA2B,CAAC,CAAC,CAAC,CAAC;IACtE,gCAAgC;IAChC,QAAQ,CAAC,UAAU,EAAE,SAAS,iCAAiC,EAAE,CAAC;CACnE;AAED,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,0EAA0E;AAC1E,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;gBACnB,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM;CAKnD;AAOD,sDAAsD;AACtD,qBAAa,wBAAyB,YAAW,sBAAsB;IACrE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2C;IAClE,OAAO,CAAC,MAAM,CAAS;gBAEX,aAAa,CAAC,EAAE,MAAM;IAIlC,IAAI,UAAU,IAAI,SAAS,iCAAiC,EAAE,CAE7D;IAED,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,2BAA2B,CAAC,CAAC,CAAC;IAuCrE,0DAA0D;IAC1D,IAAI,IAAI,wBAAwB;CAIjC"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Application-facing multi-operation transactions.
3
+ *
4
+ * ```ts
5
+ * const result = await db.transaction(async tx => {
6
+ * tx.collection('users').set('u1', user);
7
+ * tx.collection('orders').set('o1', order);
8
+ * tx.collection('audit').set('a1', event);
9
+ * });
10
+ * ```
11
+ *
12
+ * Either every operation commits or none do.
13
+ *
14
+ * The callback **stages** operations; it does not write them. Nothing reaches
15
+ * the authority until the callback returns, at which point the whole
16
+ * transaction is sent as one request and committed as one durable record. That
17
+ * is what makes the guarantee real: there is no window in which some of the
18
+ * operations have been written and others have not.
19
+ *
20
+ * FeltDB does not implement a second transaction mechanism in TypeScript. This
21
+ * builder produces a request for the store's own atomic transaction path, and
22
+ * a runtime that cannot provide that path refuses the transaction rather than
23
+ * silently degrading it into a sequence of independent writes.
24
+ */
25
+ /** Thrown when a transaction cannot be committed. Nothing was applied. */
26
+ export class AtomicTransactionError extends Error {
27
+ constructor(message, transactionId) {
28
+ super(message);
29
+ this.name = 'AtomicTransactionError';
30
+ this.transactionId = transactionId;
31
+ }
32
+ }
33
+ function generateTransactionId() {
34
+ const random = Math.random().toString(36).slice(2, 10);
35
+ return `tx_${Date.now().toString(36)}_${random}`;
36
+ }
37
+ /** Collects operations without performing any I/O. */
38
+ export class AtomicTransactionBuilder {
39
+ constructor(transactionId) {
40
+ this.staged = [];
41
+ this.sealed = false;
42
+ this.transactionId = transactionId || generateTransactionId();
43
+ }
44
+ get operations() {
45
+ return this.staged;
46
+ }
47
+ collection(name) {
48
+ if (!name || !name.trim())
49
+ throw new Error('collection name is required');
50
+ const stage = (operation) => {
51
+ if (this.sealed) {
52
+ throw new Error('this transaction has already been committed; start a new one');
53
+ }
54
+ const duplicate = this.staged.find(existing => existing.collection === operation.collection && existing.id === operation.id);
55
+ if (duplicate) {
56
+ // Two writes to one record inside one transaction would make the
57
+ // outcome depend on staging order rather than on the transaction.
58
+ throw new Error(`transaction already stages ${operation.collection}:${operation.id}; `
59
+ + 'a transaction may write each record at most once');
60
+ }
61
+ this.staged.push(operation);
62
+ };
63
+ const surface = {
64
+ set: (id, value, options) => {
65
+ stage({
66
+ collection: name,
67
+ id: String(id),
68
+ value: value,
69
+ requireAbsent: options?.requireAbsent,
70
+ });
71
+ return surface;
72
+ },
73
+ insert: (value, id, options) => surface.set(id, value, options),
74
+ delete: (id, options) => {
75
+ stage({ collection: name, id: String(id), requireAbsent: options?.requireAbsent });
76
+ return surface;
77
+ },
78
+ };
79
+ return surface;
80
+ }
81
+ /** Freeze the builder and produce the request to send. */
82
+ seal() {
83
+ this.sealed = true;
84
+ return { transactionId: this.transactionId, operations: [...this.staged] };
85
+ }
86
+ }
Binary file
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Browser-safe Development Workspace surface.
3
+ *
4
+ * The workspace module also contains the CLI-side supervisor, the durable
5
+ * investigation store, the local development authority, and Git inspection.
6
+ * Those need Node built-ins, so they are exported from `workspace/index.ts`
7
+ * and reach applications through the Node entry point only.
8
+ *
9
+ * What remains here is everything a browser genuinely uses: the runtime
10
+ * observer, the observation contract, and the workspace connection.
11
+ */
12
+ export type { DevelopmentWorkspace, ClientType, WorkspaceEventPayload, DevelopmentTask, CodeChange, VerificationResult, SourceLocation, WorkspaceClient, WorkspaceDiscovery, InvestigationState, RemediationState, VerificationState, RuntimeRequestObservation, VerificationCriterion, RemediationContract, RuntimeInvestigation, WorkspaceActivity, VerificationAttempt, CorrelatedRuntimeEvent, RuntimeObservationCorrelation, InvestigationEvidence, InvestigationFinding, RepositoryIdentity, RemediationTracking, } from './workspace-types.js';
13
+ export { RUNTIME_OBSERVATION_COLLECTION, REDACTED_PARAMETER_PATTERNS, REDACTION_PLACEHOLDER, redactUrl, redactMessage, describeBrowser, isActionableRuntimeDefect, describeDefect, createRuntimeObservation, createObservationId, createCorrelationId, } from './runtime-observation.js';
14
+ export type { RuntimeObservationInput } from './runtime-observation.js';
15
+ export { startRuntimeObservation } from './runtime-observer.js';
16
+ export type { RuntimeObservationOptions, RuntimeObservationHandle } from './runtime-observer.js';
17
+ export { collectEvidence, deriveFinding, candidateSourcePaths, recommendChanges, resolveRelevantSource, verificationContractFor, summarizeDefect, } from './investigation-analysis.js';
18
+ export { RUNTIME_INVESTIGATION_COLLECTION, LEGACY_RUNTIME_INVESTIGATION_COLLECTION, transitionInvestigation, transitionRemediation, transitionVerification, createRemediationContract, classifyWorkspaceActivity, evaluateVerification, agentRemediationHandoff, RUNTIME_INVESTIGATION_INSTRUCTIONS, FELTDB_OBSERVATION_BOUNDARY, } from './runtime-investigation.js';
19
+ export type { WorkspaceConnectionOptions, WorkspaceMetadata, PairingTokenData, BrowserPairingResolution, PairingDiscoveryOptions, ClientInfo, } from './workspace-connection.js';
20
+ export { connectDevelopmentWorkspace, discoverDevelopmentWorkspace, resolvePairingCode, DevelopmentWorkspaceConnection, } from './workspace-connection.js';
21
+ export { createWorkspaceId, isValidWorkspaceId, createDevelopmentWorkspace, updateWorkspaceTimestamp, discoverWorkspace, persistWorkspaceDiscovery, } from './workspace-identity.js';
22
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/workspace/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,YAAY,EACV,oBAAoB,EACpB,UAAU,EACV,qBAAqB,EACrB,eAAe,EACf,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,yBAAyB,EACzB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,6BAA6B,EAC7B,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,8BAA8B,EAC9B,2BAA2B,EAC3B,qBAAqB,EACrB,SAAS,EACT,aAAa,EACb,eAAe,EACf,yBAAyB,EACzB,cAAc,EACd,wBAAwB,EACxB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAExE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,YAAY,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAEjG,OAAO,EACL,eAAe,EACf,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,eAAe,GAChB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,gCAAgC,EAChC,uCAAuC,EACvC,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,oBAAoB,EACpB,uBAAuB,EACvB,kCAAkC,EAClC,2BAA2B,GAC5B,MAAM,4BAA4B,CAAC;AAEpC,YAAY,EACV,0BAA0B,EAC1B,iBAAiB,EACjB,gBAAgB,EAChB,wBAAwB,EACxB,uBAAuB,EACvB,UAAU,GACX,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,2BAA2B,EAC3B,4BAA4B,EAC5B,kBAAkB,EAClB,8BAA8B,GAC/B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,0BAA0B,EAC1B,wBAAwB,EACxB,iBAAiB,EACjB,yBAAyB,GAC1B,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Browser-safe Development Workspace surface.
3
+ *
4
+ * The workspace module also contains the CLI-side supervisor, the durable
5
+ * investigation store, the local development authority, and Git inspection.
6
+ * Those need Node built-ins, so they are exported from `workspace/index.ts`
7
+ * and reach applications through the Node entry point only.
8
+ *
9
+ * What remains here is everything a browser genuinely uses: the runtime
10
+ * observer, the observation contract, and the workspace connection.
11
+ */
12
+ export { RUNTIME_OBSERVATION_COLLECTION, REDACTED_PARAMETER_PATTERNS, REDACTION_PLACEHOLDER, redactUrl, redactMessage, describeBrowser, isActionableRuntimeDefect, describeDefect, createRuntimeObservation, createObservationId, createCorrelationId, } from './runtime-observation.js';
13
+ export { startRuntimeObservation } from './runtime-observer.js';
14
+ export { collectEvidence, deriveFinding, candidateSourcePaths, recommendChanges, resolveRelevantSource, verificationContractFor, summarizeDefect, } from './investigation-analysis.js';
15
+ export { RUNTIME_INVESTIGATION_COLLECTION, LEGACY_RUNTIME_INVESTIGATION_COLLECTION, transitionInvestigation, transitionRemediation, transitionVerification, createRemediationContract, classifyWorkspaceActivity, evaluateVerification, agentRemediationHandoff, RUNTIME_INVESTIGATION_INSTRUCTIONS, FELTDB_OBSERVATION_BOUNDARY, } from './runtime-investigation.js';
16
+ export { connectDevelopmentWorkspace, discoverDevelopmentWorkspace, resolvePairingCode, DevelopmentWorkspaceConnection, } from './workspace-connection.js';
17
+ export { createWorkspaceId, isValidWorkspaceId, createDevelopmentWorkspace, updateWorkspaceTimestamp, discoverWorkspace, persistWorkspaceDiscovery, } from './workspace-identity.js';
@@ -14,6 +14,7 @@ export declare class DevelopmentNode {
14
14
  private tasks;
15
15
  private codeChanges;
16
16
  private verificationResults;
17
+ private runtimeObservations;
17
18
  private investigations;
18
19
  private remediationContracts;
19
20
  private workspaceActivities;
@@ -35,8 +36,22 @@ export declare class DevelopmentNode {
35
36
  publishVerificationResult(result: Omit<VerificationResult, 'id' | 'createdAt'>): Promise<VerificationResult>;
36
37
  getVerificationResult(resultId: string): Promise<VerificationResult | null>;
37
38
  listVerificationResults(taskId: string): Promise<VerificationResult[]>;
39
+ /** Persist an immutable canonical runtime observation. */
40
+ recordRuntimeObservation(observation: RuntimeRequestObservation): Promise<RuntimeRequestObservation>;
41
+ getRuntimeObservation(observationId: string): Promise<RuntimeRequestObservation | null>;
38
42
  createRuntimeInvestigation(workspaceId: string, contract: RemediationContract): Promise<RuntimeInvestigation>;
39
43
  getRuntimeInvestigation(id: string): Promise<RuntimeInvestigation | null>;
44
+ /**
45
+ * Link another immutable observation to an investigation. One investigation
46
+ * may aggregate many observations; one observation belongs to at most one.
47
+ */
48
+ linkRuntimeObservationToInvestigation(observationId: string, investigationId: string): Promise<RuntimeInvestigation>;
49
+ getRuntimeInvestigationForObservation(observationId: string): Promise<RuntimeInvestigation | null>;
50
+ /** Associate existing development change/verification records without mutating observations. */
51
+ linkRuntimeInvestigation(investigationId: string, links: {
52
+ changeId?: string;
53
+ verificationId?: string;
54
+ }): Promise<RuntimeInvestigation>;
40
55
  getRemediationContract(id: string): Promise<RemediationContract | null>;
41
56
  advanceInvestigation(id: string, next: RuntimeInvestigation['investigationState']): Promise<RuntimeInvestigation>;
42
57
  advanceRemediation(id: string, next: RuntimeInvestigation['remediationState']): Promise<RuntimeInvestigation>;
@@ -47,6 +62,7 @@ export declare class DevelopmentNode {
47
62
  listWorkspaceActivities(investigationId: string): Promise<WorkspaceActivity[]>;
48
63
  listVerificationAttempts(investigationId: string): Promise<VerificationAttempt[]>;
49
64
  private requireInvestigation;
65
+ private investigationObservationIds;
50
66
  private validateWorkspaceExists;
51
67
  private ensureRunning;
52
68
  private generateId;
@@ -1 +1 @@
1
- {"version":3,"file":"development-node.d.ts","sourceRoot":"","sources":["../../src/workspace/development-node.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,oBAAoB,EAEpB,eAAe,EACf,UAAU,EACV,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,yBAAyB,EACzB,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,sBAAsB,CAAC;AAc9B,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,UAAU,CAAgD;IAClE,OAAO,CAAC,KAAK,CAA2C;IACxD,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,mBAAmB,CAA8C;IACzE,OAAO,CAAC,cAAc,CAAgD;IACtE,OAAO,CAAC,oBAAoB,CAA+C;IAC3E,OAAO,CAAC,mBAAmB,CAA6C;IACxE,OAAO,CAAC,oBAAoB,CAA+C;IAC3E,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,GAAE,qBAA0B;IAIxC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IActB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAcrB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAU/E,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAUvE,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAYnE,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC;IAmBpG,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAKxD,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAO1D,iBAAiB,CACrB,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,CAAC,GACzD,OAAO,CAAC,UAAU,CAAC;IAmBhB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAK3D,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAMtD,yBAAyB,CAC7B,MAAM,EAAE,IAAI,CAAC,kBAAkB,EAAE,IAAI,GAAG,WAAW,CAAC,GACnD,OAAO,CAAC,kBAAkB,CAAC;IAiBxB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAK3E,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAMtE,0BAA0B,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAmB7G,uBAAuB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAKzE,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IAKvE,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,CAAC,oBAAoB,CAAC,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAQjH,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAQ7G,uBAAuB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAWhF,0BAA0B,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IASrE,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAO5D,0BAA0B,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,yBAAyB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAY7G,uBAAuB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAK9E,wBAAwB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAKvF,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,uBAAuB;IAM/B,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,UAAU;YAIJ,SAAS;YA+CT,SAAS;CA2BxB;AAID,wBAAsB,kBAAkB,CAAC,MAAM,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CAOjG;AAED,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CAK7D"}
1
+ {"version":3,"file":"development-node.d.ts","sourceRoot":"","sources":["../../src/workspace/development-node.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,7 @@ export class DevelopmentNode {
12
12
  this.tasks = new Map();
13
13
  this.codeChanges = new Map();
14
14
  this.verificationResults = new Map();
15
+ this.runtimeObservations = new Map();
15
16
  this.investigations = new Map();
16
17
  this.remediationContracts = new Map();
17
18
  this.workspaceActivities = new Map();
@@ -135,6 +136,26 @@ export class DevelopmentNode {
135
136
  this.ensureRunning();
136
137
  return Array.from(this.verificationResults.values()).filter((r) => r.taskId === taskId);
137
138
  }
139
+ /** Persist an immutable canonical runtime observation. */
140
+ async recordRuntimeObservation(observation) {
141
+ this.ensureRunning();
142
+ if (!observation.observationId)
143
+ throw new Error('Runtime observation requires observationId');
144
+ if (this.runtimeObservations.has(observation.observationId)) {
145
+ throw new Error(`Runtime observation already exists: ${observation.observationId}`);
146
+ }
147
+ if (observation.workspaceId)
148
+ this.validateWorkspaceExists(observation.workspaceId);
149
+ const stored = JSON.parse(JSON.stringify(observation));
150
+ this.runtimeObservations.set(stored.observationId, stored);
151
+ await this.saveState();
152
+ return JSON.parse(JSON.stringify(stored));
153
+ }
154
+ async getRuntimeObservation(observationId) {
155
+ this.ensureRunning();
156
+ const observation = this.runtimeObservations.get(observationId);
157
+ return observation ? JSON.parse(JSON.stringify(observation)) : null;
158
+ }
138
159
  async createRuntimeInvestigation(workspaceId, contract) {
139
160
  this.ensureRunning();
140
161
  this.validateWorkspaceExists(workspaceId);
@@ -145,6 +166,9 @@ export class DevelopmentNode {
145
166
  id: contract.investigationId,
146
167
  workspaceId,
147
168
  observationId: contract.observationId,
169
+ observationIds: [contract.observationId],
170
+ runtimeInstanceId: contract.originalObservation.runtimeInstanceId,
171
+ sessionId: contract.originalObservation.sessionId,
148
172
  remediationContractId: contract.id,
149
173
  investigationState: 'OBSERVED', remediationState: 'NOT_STARTED', verificationState: 'NOT_READY',
150
174
  createdAt: now, updatedAt: now,
@@ -158,6 +182,52 @@ export class DevelopmentNode {
158
182
  this.ensureRunning();
159
183
  return this.investigations.get(id) || null;
160
184
  }
185
+ /**
186
+ * Link another immutable observation to an investigation. One investigation
187
+ * may aggregate many observations; one observation belongs to at most one.
188
+ */
189
+ async linkRuntimeObservationToInvestigation(observationId, investigationId) {
190
+ this.ensureRunning();
191
+ const observation = this.runtimeObservations.get(observationId);
192
+ if (!observation)
193
+ throw new Error(`Runtime observation not found: ${observationId}`);
194
+ const investigation = this.requireInvestigation(investigationId);
195
+ if (observation.workspaceId && observation.workspaceId !== investigation.workspaceId) {
196
+ throw new Error('Runtime observation and investigation must belong to the same workspace');
197
+ }
198
+ const owner = [...this.investigations.values()].find(value => value.id !== investigationId && this.investigationObservationIds(value).includes(observationId));
199
+ if (owner)
200
+ throw new Error(`Runtime observation ${observationId} is already linked to ${owner.id}`);
201
+ const observationIds = this.investigationObservationIds(investigation);
202
+ if (!observationIds.includes(observationId))
203
+ observationIds.push(observationId);
204
+ const updated = { ...investigation, observationIds, updatedAt: Date.now() };
205
+ this.investigations.set(investigationId, updated);
206
+ await this.saveState();
207
+ return updated;
208
+ }
209
+ async getRuntimeInvestigationForObservation(observationId) {
210
+ this.ensureRunning();
211
+ return [...this.investigations.values()].find(value => this.investigationObservationIds(value).includes(observationId)) || null;
212
+ }
213
+ /** Associate existing development change/verification records without mutating observations. */
214
+ async linkRuntimeInvestigation(investigationId, links) {
215
+ const investigation = this.requireInvestigation(investigationId);
216
+ if (links.changeId) {
217
+ const change = this.codeChanges.get(links.changeId);
218
+ if (!change || change.workspaceId !== investigation.workspaceId)
219
+ throw new Error(`Code change not found in workspace: ${links.changeId}`);
220
+ }
221
+ if (links.verificationId) {
222
+ const verification = this.verificationResults.get(links.verificationId);
223
+ if (!verification || verification.workspaceId !== investigation.workspaceId)
224
+ throw new Error(`Verification result not found in workspace: ${links.verificationId}`);
225
+ }
226
+ const updated = { ...investigation, ...links, updatedAt: Date.now() };
227
+ this.investigations.set(investigationId, updated);
228
+ await this.saveState();
229
+ return updated;
230
+ }
161
231
  async getRemediationContract(id) {
162
232
  this.ensureRunning();
163
233
  return this.remediationContracts.get(id) || null;
@@ -209,7 +279,15 @@ export class DevelopmentNode {
209
279
  throw new Error(`Remediation contract not found: ${current.remediationContractId}`);
210
280
  const attempt = evaluateVerification(contract, observation);
211
281
  this.verificationAttempts.set(attempt.id, attempt);
212
- this.investigations.set(id, transitionVerification(current, attempt.result));
282
+ const updated = transitionVerification(current, attempt.result);
283
+ updated.verificationId = attempt.verificationId;
284
+ if (observation) {
285
+ updated.observationIds = [...new Set([
286
+ ...this.investigationObservationIds(updated),
287
+ observation.observationId,
288
+ ])];
289
+ }
290
+ this.investigations.set(id, updated);
213
291
  await this.saveState();
214
292
  return attempt;
215
293
  }
@@ -228,6 +306,9 @@ export class DevelopmentNode {
228
306
  throw new Error(`Investigation not found: ${id}`);
229
307
  return investigation;
230
308
  }
309
+ investigationObservationIds(investigation) {
310
+ return [...new Set([investigation.observationId, ...(investigation.observationIds || [])].filter(Boolean))];
311
+ }
231
312
  validateWorkspaceExists(workspaceId) {
232
313
  if (!this.workspaces.has(workspaceId)) {
233
314
  throw new Error(`Workspace not found: ${workspaceId}`);
@@ -256,6 +337,7 @@ export class DevelopmentNode {
256
337
  this.tasks = new Map(Object.entries(state.tasks || {}));
257
338
  this.codeChanges = new Map(Object.entries(state.codeChanges || {}));
258
339
  this.verificationResults = new Map(Object.entries(state.verificationResults || {}));
340
+ this.runtimeObservations = new Map(Object.entries(state.runtimeObservations || {}));
259
341
  this.investigations = new Map(Object.entries(state.investigations || {}));
260
342
  this.remediationContracts = new Map(Object.entries(state.remediationContracts || {}));
261
343
  this.workspaceActivities = new Map(Object.entries(state.workspaceActivities || {}));
@@ -266,6 +348,7 @@ export class DevelopmentNode {
266
348
  this.tasks.clear();
267
349
  this.codeChanges.clear();
268
350
  this.verificationResults.clear();
351
+ this.runtimeObservations.clear();
269
352
  this.investigations.clear();
270
353
  this.remediationContracts.clear();
271
354
  this.workspaceActivities.clear();
@@ -289,6 +372,7 @@ export class DevelopmentNode {
289
372
  tasks: Object.fromEntries(this.tasks),
290
373
  codeChanges: Object.fromEntries(this.codeChanges),
291
374
  verificationResults: Object.fromEntries(this.verificationResults),
375
+ runtimeObservations: Object.fromEntries(this.runtimeObservations),
292
376
  investigations: Object.fromEntries(this.investigations),
293
377
  remediationContracts: Object.fromEntries(this.remediationContracts),
294
378
  workspaceActivities: Object.fromEntries(this.workspaceActivities),
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Git-backed remediation identity.
3
+ *
4
+ * FeltDB does not trust an agent's claim that it changed the code. It captures
5
+ * observable repository state before handing an investigation to the agent and
6
+ * again afterwards, and treats the difference as evidence that remediation
7
+ * occurred.
8
+ *
9
+ * A commit is not required. An agent that edits the working tree without
10
+ * committing has still changed the repository, so the working-tree digest is a
11
+ * first-class change identity.
12
+ *
13
+ * Detecting a repository change proves that remediation happened. It does not
14
+ * prove the defect is fixed — only a runtime observation can do that.
15
+ */
16
+ import type { RemediationTracking, RepositoryIdentity } from './workspace-types.js';
17
+ /**
18
+ * Capture the observable identity of a repository working tree.
19
+ *
20
+ * The digest covers `git status --porcelain` plus the content of every
21
+ * modified or untracked file, so an uncommitted edit changes the identity.
22
+ */
23
+ export declare function captureRepositoryIdentity(dir: string): RepositoryIdentity;
24
+ /** Paths reported as changed by `git status --porcelain`. */
25
+ export declare function changedPaths(dir: string): string[];
26
+ /** Whether two repository identities describe different repository states. */
27
+ export declare function repositoryChanged(before: RepositoryIdentity, after: RepositoryIdentity): boolean;
28
+ /**
29
+ * Compare the repository before and after an agent worked, and describe the
30
+ * change in a form that answers both directions of the question:
31
+ * "what changed because of this investigation?" and
32
+ * "which investigation caused this change?"
33
+ */
34
+ export declare function trackRemediation(investigationId: string, before: RepositoryIdentity, dir: string): RemediationTracking;
35
+ //# sourceMappingURL=git-identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-identity.d.ts","sourceRoot":"","sources":["../../src/workspace/git-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAOpF;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAmBzE;AAED,6DAA6D;AAC7D,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CASlD;AAED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,EAAE,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAEhG;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,kBAAkB,EAC1B,GAAG,EAAE,MAAM,GACV,mBAAmB,CAarB"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Git-backed remediation identity.
3
+ *
4
+ * FeltDB does not trust an agent's claim that it changed the code. It captures
5
+ * observable repository state before handing an investigation to the agent and
6
+ * again afterwards, and treats the difference as evidence that remediation
7
+ * occurred.
8
+ *
9
+ * A commit is not required. An agent that edits the working tree without
10
+ * committing has still changed the repository, so the working-tree digest is a
11
+ * first-class change identity.
12
+ *
13
+ * Detecting a repository change proves that remediation happened. It does not
14
+ * prove the defect is fixed — only a runtime observation can do that.
15
+ */
16
+ import { spawnSync } from 'node:child_process';
17
+ import { createHash } from 'node:crypto';
18
+ function git(dir, args) {
19
+ const result = spawnSync('git', ['-C', dir, ...args], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
20
+ return { ok: result.status === 0, stdout: (result.stdout || '').trim() };
21
+ }
22
+ /**
23
+ * Capture the observable identity of a repository working tree.
24
+ *
25
+ * The digest covers `git status --porcelain` plus the content of every
26
+ * modified or untracked file, so an uncommitted edit changes the identity.
27
+ */
28
+ export function captureRepositoryIdentity(dir) {
29
+ const head = git(dir, ['rev-parse', 'HEAD']);
30
+ const branch = git(dir, ['rev-parse', '--abbrev-ref', 'HEAD']);
31
+ const status = git(dir, ['status', '--porcelain']);
32
+ const hash = createHash('sha256');
33
+ hash.update(status.stdout);
34
+ // `git stash create` would mutate state; hashing the diff of tracked files
35
+ // plus the porcelain status is enough to identify a working-tree revision.
36
+ const diff = git(dir, ['diff', 'HEAD']);
37
+ hash.update(diff.stdout);
38
+ return {
39
+ head: head.ok && head.stdout ? head.stdout : null,
40
+ branch: branch.ok ? branch.stdout : undefined,
41
+ workingTreeDigest: hash.digest('hex'),
42
+ dirty: status.stdout.length > 0,
43
+ capturedAt: Date.now(),
44
+ };
45
+ }
46
+ /** Paths reported as changed by `git status --porcelain`. */
47
+ export function changedPaths(dir) {
48
+ const status = git(dir, ['status', '--porcelain']);
49
+ if (!status.ok)
50
+ return [];
51
+ return status.stdout
52
+ .split('\n')
53
+ .map(line => line.slice(3).trim())
54
+ .filter(Boolean)
55
+ // A rename is reported as `old -> new`; the new path is what changed.
56
+ .map(path => (path.includes(' -> ') ? path.split(' -> ')[1] : path));
57
+ }
58
+ /** Whether two repository identities describe different repository states. */
59
+ export function repositoryChanged(before, after) {
60
+ return before.head !== after.head || before.workingTreeDigest !== after.workingTreeDigest;
61
+ }
62
+ /**
63
+ * Compare the repository before and after an agent worked, and describe the
64
+ * change in a form that answers both directions of the question:
65
+ * "what changed because of this investigation?" and
66
+ * "which investigation caused this change?"
67
+ */
68
+ export function trackRemediation(investigationId, before, dir) {
69
+ const after = captureRepositoryIdentity(dir);
70
+ const changed = repositoryChanged(before, after);
71
+ const committed = before.head !== after.head && after.head !== null;
72
+ return {
73
+ investigationId,
74
+ gitBefore: before,
75
+ gitAfter: after,
76
+ changedPaths: changed ? changedPaths(dir) : [],
77
+ changeIdentity: changed ? (committed ? after.head : after.workingTreeDigest) : undefined,
78
+ changeKind: changed ? (committed ? 'commit' : 'working_tree') : undefined,
79
+ detectedAt: changed ? Date.now() : undefined,
80
+ };
81
+ }
@@ -11,8 +11,16 @@
11
11
  * These enable any client (browser, IDE, agent) to discover and connect
12
12
  * to the same shared development workspace.
13
13
  */
14
- export type { DevelopmentWorkspace, ClientType, WorkspaceEventPayload, DevelopmentTask, CodeChange, VerificationResult, SourceLocation, WorkspaceClient, WorkspaceDiscovery, InvestigationState, RemediationState, VerificationState, RuntimeRequestObservation, VerificationCriterion, RemediationContract, RuntimeInvestigation, WorkspaceActivity, VerificationAttempt, } from './workspace-types.js';
15
- export { transitionInvestigation, transitionRemediation, transitionVerification, createRemediationContract, classifyWorkspaceActivity, evaluateVerification, agentRemediationHandoff, RUNTIME_INVESTIGATION_INSTRUCTIONS, FELTDB_OBSERVATION_BOUNDARY, } from './runtime-investigation.js';
14
+ export type { DevelopmentWorkspace, ClientType, WorkspaceEventPayload, DevelopmentTask, CodeChange, VerificationResult, SourceLocation, WorkspaceClient, WorkspaceDiscovery, WorkspaceSources, WorkspaceDefinition, WorkspaceRuntimeState, WorkspaceModel, ApplicationLifecycle, DevelopmentSessionState, DevelopmentSession, InvestigationState, RemediationState, VerificationState, RuntimeRequestObservation, VerificationCriterion, RemediationContract, RuntimeInvestigation, WorkspaceActivity, VerificationAttempt, CorrelatedRuntimeEvent, RuntimeObservationCorrelation, InvestigationEvidence, InvestigationFinding, RepositoryIdentity, RemediationTracking, } from './workspace-types.js';
15
+ export { RUNTIME_OBSERVATION_COLLECTION, REDACTED_PARAMETER_PATTERNS, REDACTION_PLACEHOLDER, redactUrl, redactMessage, describeBrowser, isActionableRuntimeDefect, describeDefect, createRuntimeObservation, createObservationId, createCorrelationId, } from './runtime-observation.js';
16
+ export type { RuntimeObservationInput } from './runtime-observation.js';
17
+ export { startRuntimeObservation } from './runtime-observer.js';
18
+ export type { RuntimeObservationOptions, RuntimeObservationHandle } from './runtime-observer.js';
19
+ export { collectEvidence, deriveFinding, candidateSourcePaths, recommendChanges, resolveRelevantSource, verificationContractFor, summarizeDefect, } from './investigation-analysis.js';
20
+ export { captureRepositoryIdentity, changedPaths, repositoryChanged, trackRemediation, } from './git-identity.js';
21
+ export { RuntimeInvestigationSupervisor } from './investigation-supervisor.js';
22
+ export type { SupervisorOptions, AgentHandoffArtifact } from './investigation-supervisor.js';
23
+ export { RUNTIME_INVESTIGATION_COLLECTION, LEGACY_RUNTIME_INVESTIGATION_COLLECTION, transitionInvestigation, transitionRemediation, transitionVerification, createRemediationContract, classifyWorkspaceActivity, evaluateVerification, agentRemediationHandoff, RUNTIME_INVESTIGATION_INSTRUCTIONS, FELTDB_OBSERVATION_BOUNDARY, } from './runtime-investigation.js';
16
24
  export type { WorkspaceConnectionOptions, WorkspaceMetadata, PairingTokenData, BrowserPairingResolution, PairingDiscoveryOptions, ClientInfo, } from './workspace-connection.js';
17
25
  export { connectDevelopmentWorkspace, discoverDevelopmentWorkspace, resolvePairingCode, DevelopmentWorkspaceConnection, } from './workspace-connection.js';
18
26
  export { createWorkspaceId, isValidWorkspaceId, createDevelopmentWorkspace, updateWorkspaceTimestamp, discoverWorkspace, persistWorkspaceDiscovery, } from './workspace-identity.js';
@@ -20,4 +28,6 @@ export { DevelopmentNode, getDevelopmentNode, shutdownDevelopmentNode, } from '.
20
28
  export type { DevelopmentNodeConfig } from './development-node.js';
21
29
  export { startLocalDevelopmentAuthority } from './local-development-authority.js';
22
30
  export type { LocalDevelopmentAuthority, LocalDevelopmentAuthorityOptions } from './local-development-authority.js';
31
+ export { InvestigationLifecycleManager } from './investigation-lifecycle-manager.js';
32
+ export type { InvestigationStoreMetrics } from './investigation-lifecycle-manager.js';
23
33
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/workspace/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,YAAY,EACV,oBAAoB,EACpB,UAAU,EACV,qBAAqB,EACrB,eAAe,EACf,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,yBAAyB,EACzB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,oBAAoB,EACpB,uBAAuB,EACvB,kCAAkC,EAClC,2BAA2B,GAC5B,MAAM,4BAA4B,CAAC;AAEpC,YAAY,EACV,0BAA0B,EAC1B,iBAAiB,EACjB,gBAAgB,EAChB,wBAAwB,EACxB,uBAAuB,EACvB,UAAU,GACX,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,2BAA2B,EAC3B,4BAA4B,EAC5B,kBAAkB,EAClB,8BAA8B,GAC/B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,0BAA0B,EAC1B,wBAAwB,EACxB,iBAAiB,EACjB,yBAAyB,GAC1B,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAEnE,OAAO,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AAClF,YAAY,EAAE,yBAAyB,EAAE,gCAAgC,EAAE,MAAM,kCAAkC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/workspace/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,YAAY,EACV,oBAAoB,EACpB,UAAU,EACV,qBAAqB,EACrB,eAAe,EACf,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,cAAc,EACd,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,yBAAyB,EACzB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,6BAA6B,EAC7B,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,8BAA8B,EAC9B,2BAA2B,EAC3B,qBAAqB,EACrB,SAAS,EACT,aAAa,EACb,eAAe,EACf,yBAAyB,EACzB,cAAc,EACd,wBAAwB,EACxB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAExE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,YAAY,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAEjG,OAAO,EACL,eAAe,EACf,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,eAAe,GAChB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,yBAAyB,EACzB,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,8BAA8B,EAAE,MAAM,+BAA+B,CAAC;AAC/E,YAAY,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAE7F,OAAO,EACL,gCAAgC,EAChC,uCAAuC,EACvC,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,oBAAoB,EACpB,uBAAuB,EACvB,kCAAkC,EAClC,2BAA2B,GAC5B,MAAM,4BAA4B,CAAC;AAEpC,YAAY,EACV,0BAA0B,EAC1B,iBAAiB,EACjB,gBAAgB,EAChB,wBAAwB,EACxB,uBAAuB,EACvB,UAAU,GACX,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,2BAA2B,EAC3B,4BAA4B,EAC5B,kBAAkB,EAClB,8BAA8B,GAC/B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,0BAA0B,EAC1B,wBAAwB,EACxB,iBAAiB,EACjB,yBAAyB,GAC1B,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAEnE,OAAO,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AAClF,YAAY,EAAE,yBAAyB,EAAE,gCAAgC,EAAE,MAAM,kCAAkC,CAAC;AAEpH,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AACrF,YAAY,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC"}
@@ -11,8 +11,14 @@
11
11
  * These enable any client (browser, IDE, agent) to discover and connect
12
12
  * to the same shared development workspace.
13
13
  */
14
- export { transitionInvestigation, transitionRemediation, transitionVerification, createRemediationContract, classifyWorkspaceActivity, evaluateVerification, agentRemediationHandoff, RUNTIME_INVESTIGATION_INSTRUCTIONS, FELTDB_OBSERVATION_BOUNDARY, } from './runtime-investigation.js';
14
+ export { RUNTIME_OBSERVATION_COLLECTION, REDACTED_PARAMETER_PATTERNS, REDACTION_PLACEHOLDER, redactUrl, redactMessage, describeBrowser, isActionableRuntimeDefect, describeDefect, createRuntimeObservation, createObservationId, createCorrelationId, } from './runtime-observation.js';
15
+ export { startRuntimeObservation } from './runtime-observer.js';
16
+ export { collectEvidence, deriveFinding, candidateSourcePaths, recommendChanges, resolveRelevantSource, verificationContractFor, summarizeDefect, } from './investigation-analysis.js';
17
+ export { captureRepositoryIdentity, changedPaths, repositoryChanged, trackRemediation, } from './git-identity.js';
18
+ export { RuntimeInvestigationSupervisor } from './investigation-supervisor.js';
19
+ export { RUNTIME_INVESTIGATION_COLLECTION, LEGACY_RUNTIME_INVESTIGATION_COLLECTION, transitionInvestigation, transitionRemediation, transitionVerification, createRemediationContract, classifyWorkspaceActivity, evaluateVerification, agentRemediationHandoff, RUNTIME_INVESTIGATION_INSTRUCTIONS, FELTDB_OBSERVATION_BOUNDARY, } from './runtime-investigation.js';
15
20
  export { connectDevelopmentWorkspace, discoverDevelopmentWorkspace, resolvePairingCode, DevelopmentWorkspaceConnection, } from './workspace-connection.js';
16
21
  export { createWorkspaceId, isValidWorkspaceId, createDevelopmentWorkspace, updateWorkspaceTimestamp, discoverWorkspace, persistWorkspaceDiscovery, } from './workspace-identity.js';
17
22
  export { DevelopmentNode, getDevelopmentNode, shutdownDevelopmentNode, } from './development-node.js';
18
23
  export { startLocalDevelopmentAuthority } from './local-development-authority.js';
24
+ export { InvestigationLifecycleManager } from './investigation-lifecycle-manager.js';