@alan512/experienceengine 0.3.6 → 0.4.1

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 (137) hide show
  1. package/README.md +15 -4
  2. package/README.zh-CN.md +15 -4
  3. package/dist/adapters/antigravity/artifact-analyzer.d.ts +27 -0
  4. package/dist/adapters/antigravity/artifact-analyzer.js +151 -0
  5. package/dist/adapters/antigravity/artifact-analyzer.js.map +1 -0
  6. package/dist/adapters/codex/behavior-loop.d.ts +15 -43
  7. package/dist/adapters/codex/behavior-loop.js +2 -215
  8. package/dist/adapters/codex/behavior-loop.js.map +1 -1
  9. package/dist/adapters/codex/mcp-server.d.ts +37 -44
  10. package/dist/adapters/codex/mcp-server.js +5 -427
  11. package/dist/adapters/codex/mcp-server.js.map +1 -1
  12. package/dist/adapters/shared-mcp/action-registry.d.ts +121 -0
  13. package/dist/adapters/shared-mcp/action-registry.js +435 -0
  14. package/dist/adapters/shared-mcp/action-registry.js.map +1 -0
  15. package/dist/adapters/shared-mcp/behavior-loop.d.ts +91 -0
  16. package/dist/adapters/shared-mcp/behavior-loop.js +218 -0
  17. package/dist/adapters/shared-mcp/behavior-loop.js.map +1 -0
  18. package/dist/adapters/shared-mcp/server.d.ts +113 -0
  19. package/dist/adapters/shared-mcp/server.js +423 -0
  20. package/dist/adapters/shared-mcp/server.js.map +1 -0
  21. package/dist/cli/commands/agy-exec.d.ts +23 -0
  22. package/dist/cli/commands/agy-exec.js +92 -0
  23. package/dist/cli/commands/agy-exec.js.map +1 -0
  24. package/dist/cli/commands/antigravity-hook.d.ts +58 -0
  25. package/dist/cli/commands/antigravity-hook.js +192 -0
  26. package/dist/cli/commands/antigravity-hook.js.map +1 -0
  27. package/dist/cli/commands/antigravity.d.ts +8 -0
  28. package/dist/cli/commands/antigravity.js +37 -0
  29. package/dist/cli/commands/antigravity.js.map +1 -0
  30. package/dist/cli/commands/doctor.d.ts +2 -0
  31. package/dist/cli/commands/doctor.js +160 -3
  32. package/dist/cli/commands/doctor.js.map +1 -1
  33. package/dist/cli/commands/inspect.js +78 -1
  34. package/dist/cli/commands/inspect.js.map +1 -1
  35. package/dist/cli/commands/install.d.ts +3 -1
  36. package/dist/cli/commands/install.js +32 -2
  37. package/dist/cli/commands/install.js.map +1 -1
  38. package/dist/cli/commands/maintenance.js +80 -2
  39. package/dist/cli/commands/maintenance.js.map +1 -1
  40. package/dist/cli/commands/mcp-server.js +10 -2
  41. package/dist/cli/commands/mcp-server.js.map +1 -1
  42. package/dist/cli/commands/repair.d.ts +1 -1
  43. package/dist/cli/commands/repair.js +21 -3
  44. package/dist/cli/commands/repair.js.map +1 -1
  45. package/dist/cli/commands/upgrade.d.ts +4 -1
  46. package/dist/cli/commands/upgrade.js +25 -2
  47. package/dist/cli/commands/upgrade.js.map +1 -1
  48. package/dist/cli/dispatch.js +22 -6
  49. package/dist/cli/dispatch.js.map +1 -1
  50. package/dist/compiler/command-normalizer.d.ts +27 -0
  51. package/dist/compiler/command-normalizer.js +263 -0
  52. package/dist/compiler/command-normalizer.js.map +1 -0
  53. package/dist/compiler/trajectory-compiler.d.ts +12 -0
  54. package/dist/compiler/trajectory-compiler.js +179 -0
  55. package/dist/compiler/trajectory-compiler.js.map +1 -0
  56. package/dist/compiler/trajectory-matcher.d.ts +18 -0
  57. package/dist/compiler/trajectory-matcher.js +419 -0
  58. package/dist/compiler/trajectory-matcher.js.map +1 -0
  59. package/dist/config/config-schema.d.ts +11 -0
  60. package/dist/config/config-schema.js +9 -0
  61. package/dist/config/config-schema.js.map +1 -1
  62. package/dist/config/default-config.js +1 -0
  63. package/dist/config/default-config.js.map +1 -1
  64. package/dist/controller/candidate-retriever.d.ts +3 -1
  65. package/dist/controller/candidate-retriever.js +247 -7
  66. package/dist/controller/candidate-retriever.js.map +1 -1
  67. package/dist/controller/intervention-controller.js +48 -21
  68. package/dist/controller/intervention-controller.js.map +1 -1
  69. package/dist/controller/trigger-evaluator.d.ts +2 -1
  70. package/dist/controller/trigger-evaluator.js +10 -4
  71. package/dist/controller/trigger-evaluator.js.map +1 -1
  72. package/dist/experience-management/node-lifecycle-governance.js +25 -6
  73. package/dist/experience-management/node-lifecycle-governance.js.map +1 -1
  74. package/dist/input/fingerprint-extractor.d.ts +53 -0
  75. package/dist/input/fingerprint-extractor.js +620 -0
  76. package/dist/input/fingerprint-extractor.js.map +1 -0
  77. package/dist/install/antigravity-global-wiring.d.ts +25 -0
  78. package/dist/install/antigravity-global-wiring.js +165 -0
  79. package/dist/install/antigravity-global-wiring.js.map +1 -0
  80. package/dist/install/antigravity-project-wiring.d.ts +24 -0
  81. package/dist/install/antigravity-project-wiring.js +380 -0
  82. package/dist/install/antigravity-project-wiring.js.map +1 -0
  83. package/dist/install/antigravity.d.ts +78 -0
  84. package/dist/install/antigravity.js +169 -0
  85. package/dist/install/antigravity.js.map +1 -0
  86. package/dist/install/host-detection.d.ts +1 -1
  87. package/dist/install/host-detection.js +2 -1
  88. package/dist/install/host-detection.js.map +1 -1
  89. package/dist/install/public-install.d.ts +2 -0
  90. package/dist/install/public-install.js +8 -0
  91. package/dist/install/public-install.js.map +1 -1
  92. package/dist/interaction/operational-actions-service.d.ts +8 -5
  93. package/dist/interaction/operational-actions-service.js +36 -6
  94. package/dist/interaction/operational-actions-service.js.map +1 -1
  95. package/dist/interaction/operational-service.d.ts +3 -1
  96. package/dist/interaction/operational-service.js +9 -0
  97. package/dist/interaction/operational-service.js.map +1 -1
  98. package/dist/interaction/service.d.ts +11 -1
  99. package/dist/interaction/service.js +11 -1
  100. package/dist/interaction/service.js.map +1 -1
  101. package/dist/maintenance/vector-migrator.d.ts +37 -0
  102. package/dist/maintenance/vector-migrator.js +170 -0
  103. package/dist/maintenance/vector-migrator.js.map +1 -0
  104. package/dist/plugin/openclaw-plugin.d.ts +8 -0
  105. package/dist/runtime/prompt-service.js +10 -0
  106. package/dist/runtime/prompt-service.js.map +1 -1
  107. package/dist/runtime/service.d.ts +2 -0
  108. package/dist/runtime/service.js +127 -2
  109. package/dist/runtime/service.js.map +1 -1
  110. package/dist/store/sqlite/db.js +18 -1
  111. package/dist/store/sqlite/db.js.map +1 -1
  112. package/dist/store/sqlite/repositories/attribution-record-repo.js +12 -0
  113. package/dist/store/sqlite/repositories/attribution-record-repo.js.map +1 -1
  114. package/dist/store/sqlite/repositories/node-repo.d.ts +1 -0
  115. package/dist/store/sqlite/repositories/node-repo.js +47 -2
  116. package/dist/store/sqlite/repositories/node-repo.js.map +1 -1
  117. package/dist/store/sqlite/repositories/scope-fingerprint-repo.d.ts +8 -0
  118. package/dist/store/sqlite/repositories/scope-fingerprint-repo.js +23 -0
  119. package/dist/store/sqlite/repositories/scope-fingerprint-repo.js.map +1 -0
  120. package/dist/store/sqlite/schema.sql +26 -0
  121. package/dist/store/vector/embeddings.d.ts +4 -2
  122. package/dist/store/vector/embeddings.js +19 -6
  123. package/dist/store/vector/embeddings.js.map +1 -1
  124. package/dist/store/vector/local-provider.d.ts +1 -1
  125. package/dist/store/vector/local-provider.js +40 -8
  126. package/dist/store/vector/local-provider.js.map +1 -1
  127. package/dist/store/vector/offline-manifest.d.ts +7 -0
  128. package/dist/store/vector/offline-manifest.js +162 -0
  129. package/dist/store/vector/offline-manifest.js.map +1 -0
  130. package/dist/store/vector/provider-types.d.ts +1 -0
  131. package/dist/types/domain.d.ts +112 -2
  132. package/dist/types/plugin.d.ts +1 -0
  133. package/docs/releases/v0.4.0.md +39 -0
  134. package/docs/releases/v0.4.1.md +22 -0
  135. package/docs/user-guide.md +119 -3
  136. package/openclaw.plugin.json +1 -1
  137. package/package.json +68 -68
@@ -0,0 +1,162 @@
1
+ import { readFileSync, existsSync, mkdirSync, copyFileSync } from "node:fs";
2
+ import { join, dirname, isAbsolute } from "node:path";
3
+ import { createHash } from "node:crypto";
4
+ export const isSafeRelativePath = (p) => {
5
+ if (typeof p !== "string" || !p)
6
+ return false;
7
+ if (isAbsolute(p))
8
+ return false;
9
+ if (/^[a-zA-Z]:/.test(p))
10
+ return false;
11
+ const parts = p.split(/[/\\]/);
12
+ for (const part of parts) {
13
+ if (part === ".." || part === ".") {
14
+ return false;
15
+ }
16
+ }
17
+ return true;
18
+ };
19
+ export const calculateFileSha256 = (filePath) => {
20
+ const content = readFileSync(filePath);
21
+ return createHash("sha256").update(content).digest("hex");
22
+ };
23
+ export const validateOfflineManifest = (manifest, baseDir) => {
24
+ if (!manifest || typeof manifest !== "object") {
25
+ throw new Error("Invalid manifest format: not an object.");
26
+ }
27
+ const m = manifest;
28
+ if (typeof m.manifestVersion !== "string" || !m.manifestVersion) {
29
+ throw new Error("Missing or invalid manifestVersion.");
30
+ }
31
+ if (m.providerId !== "local") {
32
+ throw new Error(`Unsupported providerId: ${m.providerId}. Only 'local' is supported.`);
33
+ }
34
+ if (typeof m.modelId !== "string" || !m.modelId) {
35
+ throw new Error("Missing or invalid modelId.");
36
+ }
37
+ if (typeof m.dimensions !== "number" || m.dimensions <= 0) {
38
+ throw new Error("Missing or invalid dimensions.");
39
+ }
40
+ if (typeof m.preprocessingVersion !== "string" || !m.preprocessingVersion) {
41
+ throw new Error("Missing or invalid preprocessingVersion.");
42
+ }
43
+ if (!m.assets || typeof m.assets !== "object") {
44
+ throw new Error("Missing or invalid assets object.");
45
+ }
46
+ const validatedAssets = {};
47
+ const assetsObj = m.assets;
48
+ for (const [key, value] of Object.entries(assetsObj)) {
49
+ if (!value || typeof value !== "object") {
50
+ throw new Error(`Invalid asset entry for key: ${key}.`);
51
+ }
52
+ const val = value;
53
+ if (typeof val.path !== "string" || !val.path || !isSafeRelativePath(val.path)) {
54
+ throw new Error(`Missing, invalid, or unsafe path for asset: ${key}. Path traversal detected or suspected.`);
55
+ }
56
+ if (typeof val.sha256 !== "string" || !val.sha256) {
57
+ throw new Error(`Missing or invalid sha256 checksum for asset: ${key}.`);
58
+ }
59
+ // Validate file presence and sha256
60
+ const absolutePath = join(baseDir, val.path);
61
+ if (!existsSync(absolutePath)) {
62
+ throw new Error(`Asset file missing: ${absolutePath}`);
63
+ }
64
+ const actualSha256 = calculateFileSha256(absolutePath);
65
+ if (actualSha256 !== val.sha256) {
66
+ throw new Error(`Asset checksum mismatch for file ${val.path}. Expected: ${val.sha256}, Actual: ${actualSha256}`);
67
+ }
68
+ validatedAssets[key] = {
69
+ path: val.path,
70
+ sha256: val.sha256
71
+ };
72
+ }
73
+ let manifestId = typeof m.id === "string" ? m.id : undefined;
74
+ if (!manifestId) {
75
+ const assetKeysSorted = Object.keys(validatedAssets).sort();
76
+ const assetsString = assetKeysSorted
77
+ .map((key) => `${key}:${validatedAssets[key].sha256}`)
78
+ .join(";");
79
+ const idSource = `${m.modelId}|${m.dimensions}|${m.preprocessingVersion}|${assetsString}`;
80
+ manifestId = `derived-${createHash("sha256").update(idSource).digest("hex").slice(0, 16)}`;
81
+ }
82
+ return {
83
+ id: manifestId,
84
+ manifestVersion: m.manifestVersion,
85
+ providerId: m.providerId,
86
+ modelId: m.modelId,
87
+ dimensions: m.dimensions,
88
+ preprocessingVersion: m.preprocessingVersion,
89
+ assets: validatedAssets,
90
+ license: typeof m.license === "string" ? m.license : undefined,
91
+ sourceMetadata: typeof m.sourceMetadata === "object" && m.sourceMetadata !== null ? m.sourceMetadata : undefined
92
+ };
93
+ };
94
+ export const loadOfflineManifestForModel = (cacheDir, model) => {
95
+ const modelCacheDir = join(cacheDir, ...model.split("/"));
96
+ const manifestPath = join(modelCacheDir, "manifest.json");
97
+ if (!existsSync(manifestPath)) {
98
+ throw new Error(`Manifest file not found: ${manifestPath}`);
99
+ }
100
+ try {
101
+ const rawContent = readFileSync(manifestPath, "utf8");
102
+ const manifestJson = JSON.parse(rawContent);
103
+ return validateOfflineManifest(manifestJson, modelCacheDir);
104
+ }
105
+ catch (error) {
106
+ const msg = error instanceof Error ? error.message : String(error);
107
+ throw new Error(`Failed to load or validate manifest at ${manifestPath}: ${msg}`);
108
+ }
109
+ };
110
+ export const importOfflineAssetPack = async (packDir, cacheDir) => {
111
+ const manifestPath = join(packDir, "manifest.json");
112
+ if (!existsSync(manifestPath)) {
113
+ throw new Error(`Asset pack missing manifest.json at ${packDir}`);
114
+ }
115
+ // Read and validate the manifest in the staging/pack directory
116
+ let manifest;
117
+ try {
118
+ const rawContent = readFileSync(manifestPath, "utf8");
119
+ const manifestJson = JSON.parse(rawContent);
120
+ manifest = validateOfflineManifest(manifestJson, packDir);
121
+ }
122
+ catch (error) {
123
+ const msg = error instanceof Error ? error.message : String(error);
124
+ throw new Error(`Import failed during manifest validation: ${msg}`);
125
+ }
126
+ const targetModelDir = join(cacheDir, ...manifest.modelId.split("/"));
127
+ mkdirSync(targetModelDir, { recursive: true });
128
+ // Copy manifest.json
129
+ copyFileSync(manifestPath, join(targetModelDir, "manifest.json"));
130
+ // Copy all assets
131
+ for (const asset of Object.values(manifest.assets)) {
132
+ const sourcePath = join(packDir, asset.path);
133
+ const targetPath = join(targetModelDir, asset.path);
134
+ mkdirSync(dirname(targetPath), { recursive: true });
135
+ copyFileSync(sourcePath, targetPath);
136
+ }
137
+ try {
138
+ const { clearLocalEmbeddingProviderCache } = await import("./local-provider.js");
139
+ const { clearEmbeddingRuntimeCaches } = await import("./embeddings.js");
140
+ clearLocalEmbeddingProviderCache();
141
+ clearEmbeddingRuntimeCaches();
142
+ }
143
+ catch {
144
+ // Gracefully handle dynamic import edge cases
145
+ }
146
+ };
147
+ export const exportOfflineAssetPack = async (cacheDir, model, targetPackDir) => {
148
+ // Load and validate from cache
149
+ const manifest = loadOfflineManifestForModel(cacheDir, model);
150
+ const modelCacheDir = join(cacheDir, ...model.split("/"));
151
+ mkdirSync(targetPackDir, { recursive: true });
152
+ // Copy manifest.json
153
+ copyFileSync(join(modelCacheDir, "manifest.json"), join(targetPackDir, "manifest.json"));
154
+ // Copy all assets
155
+ for (const asset of Object.values(manifest.assets)) {
156
+ const sourcePath = join(modelCacheDir, asset.path);
157
+ const targetPath = join(targetPackDir, asset.path);
158
+ mkdirSync(dirname(targetPath), { recursive: true });
159
+ copyFileSync(sourcePath, targetPath);
160
+ }
161
+ };
162
+ //# sourceMappingURL=offline-manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offline-manifest.js","sourceRoot":"","sources":["../../../src/store/vector/offline-manifest.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@ export type SemanticEmbeddingProvider = {
3
3
  model: string;
4
4
  version: string;
5
5
  dimensions: number;
6
+ manifestId?: string;
6
7
  embedQuery(text: string): Promise<number[]>;
7
8
  embedPassage(text: string): Promise<number[]>;
8
9
  };
@@ -1,7 +1,7 @@
1
1
  export type TaskType = "bug_fix" | "build_debug" | "config_debug" | "test_debug" | "integration_fix" | "feature_add" | "refactor" | "performance" | "general";
2
2
  export type ResolvedTaskType = TaskType | "unknown";
3
3
  export type ExperienceState = "candidate" | "priority_candidate" | "active" | "cooling" | "retired";
4
- export type DeliveryState = "shadow_only" | "conservative_only" | "eligible" | "quarantined";
4
+ export type DeliveryState = "shadow_only" | "conservative_only" | "eligible" | "quarantined" | "shadow_probe" | "retired";
5
5
  export type ExperienceNodeType = "strategy" | "warning";
6
6
  export type PromotionSignal = "normal" | "high_value";
7
7
  export type MergeAction = "ADD" | "UPDATE" | "NONE";
@@ -88,6 +88,7 @@ export type RetrievalContext = {
88
88
  isReadOnly?: boolean;
89
89
  modulePaths?: string[];
90
90
  expectationCorrectionIntent?: boolean;
91
+ db?: any;
91
92
  };
92
93
  export type RetrievalPolicyStageName = "retrieval_context" | "hard_filter" | "shortlist" | "semantic_rerank_backfill" | "policy_enrichment" | "decision_assembly";
93
94
  export type RetrievalPolicyStageDiagnostic = {
@@ -123,7 +124,7 @@ export type ExperienceInputRecord = {
123
124
  export type TaskRun = {
124
125
  id: string;
125
126
  episode_id?: string;
126
- host: "openclaw" | "claude-code" | "codex";
127
+ host: "openclaw" | "claude-code" | "codex" | "antigravity";
127
128
  scope_id: string;
128
129
  session_id?: string;
129
130
  task_type: ResolvedTaskType;
@@ -245,6 +246,24 @@ export type ExperienceNode = {
245
246
  last_harmed_at?: string;
246
247
  quarantined_at?: string;
247
248
  quarantine_reason?: string;
249
+ embedding_manifest_id?: string;
250
+ migration_status?: 'current' | 'pending' | 'migrating' | 'failed';
251
+ migration_last_error?: string;
252
+ migration_updated_at?: string;
253
+ source_fingerprint_hash?: string;
254
+ portable_validation_evidence?: {
255
+ compatibilityClasses: Record<string, {
256
+ successReuseCount: number;
257
+ harmCount: number;
258
+ lastUsedAt: number;
259
+ }>;
260
+ };
261
+ quarantine_lease_expires_at?: string;
262
+ quarantine_original_delivery_state?: DeliveryState;
263
+ quarantine_release_attempt_count?: number;
264
+ quarantine_last_release_attempt_at?: string;
265
+ quarantine_release_reason?: string;
266
+ quarantine_no_harm_pass_count?: number;
248
267
  created_at: string;
249
268
  updated_at: string;
250
269
  };
@@ -283,6 +302,11 @@ export type AttributionRecord = {
283
302
  user_override?: "helped" | "harmed" | "neutral";
284
303
  source: AttributionSource;
285
304
  attribution_reason?: FeedbackAttributionReason | "manual_override" | "diagnostic_record";
305
+ trajectory_verdict?: string;
306
+ trajectory_confidence?: string;
307
+ trajectory_matched_expectations?: string[];
308
+ trajectory_violated_expectations?: string[];
309
+ trajectory_evidence_refs?: string[];
286
310
  created_at: string;
287
311
  resolved_at?: string;
288
312
  };
@@ -336,6 +360,7 @@ export type InjectionScorecardNode = {
336
360
  export type InjectionScorecardCandidate = {
337
361
  id: string;
338
362
  matchScorecard?: MatchScorecard;
363
+ portabilityScorecard?: PortabilityScorecard;
339
364
  semanticScore?: number;
340
365
  lexicalScore?: number;
341
366
  fusedScore?: number;
@@ -514,3 +539,88 @@ export type DistillationJob = {
514
539
  finished_at?: string;
515
540
  discarded_at?: string;
516
541
  };
542
+ export type ProjectFingerprint = {
543
+ schemaVersion: string;
544
+ fingerprintHash: string;
545
+ timestamp: number;
546
+ primaryLanguage: string;
547
+ packageManager: string;
548
+ lockfileFamily: string;
549
+ frameworks: Record<string, number>;
550
+ databaseOrORM: Record<string, number>;
551
+ testBuildTools: Record<string, number>;
552
+ hostRuntimeAdapters: Record<string, number>;
553
+ configMarkers: string[];
554
+ workspaceRootPath?: string;
555
+ projectRootScopeId?: string;
556
+ };
557
+ export type ScopeFingerprint = {
558
+ scope_id: string;
559
+ schema_version: string;
560
+ fingerprint_hash: string;
561
+ fingerprint_json: string;
562
+ created_at: string;
563
+ updated_at: string;
564
+ };
565
+ export type OfflineAssetManifest = {
566
+ id?: string;
567
+ manifestVersion: string;
568
+ providerId: string;
569
+ modelId: string;
570
+ dimensions: number;
571
+ preprocessingVersion: string;
572
+ assets: Record<string, {
573
+ path: string;
574
+ sha256: string;
575
+ }>;
576
+ license?: string;
577
+ sourceMetadata?: Record<string, unknown>;
578
+ };
579
+ export type PortabilityBand = "incompatible" | "weakly_related" | "same_family" | "validated_portable";
580
+ export type PortabilityScorecard = {
581
+ portabilityBand: PortabilityBand;
582
+ score: number;
583
+ matchedLanguage: boolean;
584
+ sharedDependencies: string[];
585
+ penalties: Array<{
586
+ dependency: string;
587
+ category: string;
588
+ penalty: number;
589
+ reason: string;
590
+ }>;
591
+ negativeEvidence: string[];
592
+ whyScore: string;
593
+ successReuseCount?: number;
594
+ harmCount?: number;
595
+ };
596
+ export type TrajectoryExpectationType = "recommend" | "avoid";
597
+ export type ExpectationActionType = "command" | "artifact" | "generic";
598
+ export type TrajectoryExpectation = {
599
+ id: string;
600
+ type: TrajectoryExpectationType;
601
+ actionType: ExpectationActionType;
602
+ toolNamePattern?: string;
603
+ commandPattern?: string;
604
+ artifactPattern?: string;
605
+ artifactAction?: "read" | "write" | "any";
606
+ originalStep: string;
607
+ ordered: boolean;
608
+ sourceField?: "recommended_steps" | "avoid_steps" | "success_signal" | "stop_condition" | "escalation_condition";
609
+ requiredForAdoption?: boolean;
610
+ };
611
+ export type CompiledTrajectoryExpectations = {
612
+ orderedExpectations: TrajectoryExpectation[];
613
+ unorderedExpectations: TrajectoryExpectation[];
614
+ };
615
+ export type NormalizedToolEvent = {
616
+ toolName: string;
617
+ commandFamily?: string;
618
+ subcommand?: string;
619
+ normalizedInput?: string;
620
+ normalizedOutput?: string;
621
+ artifactExtension?: string;
622
+ artifactName?: string;
623
+ artifactPath?: string;
624
+ artifactPaths?: string[];
625
+ status: "success" | "failure" | "unknown";
626
+ };
@@ -8,6 +8,7 @@ export type HostPromptContext = {
8
8
  taskSummary?: string;
9
9
  contextSummary?: string;
10
10
  injectedNodeIds?: string[];
11
+ outcomeSignal?: string;
11
12
  };
12
13
  export type HostToolResult = {
13
14
  sessionId?: string;
@@ -0,0 +1,39 @@
1
+ # ExperienceEngine v0.4.0
2
+
3
+ `v0.4.0` introduces the **Governed Portable Experience** layer, enabling safe cross-repository experience sharing, stack-aware compatibility fingerprinting, causal trajectory-based attribution, and a lease-based quarantine and shadow-probe lifecycle.
4
+
5
+ ## What Changed
6
+
7
+ - **Offline Embedding Profiles**: Added support for `standard`, `local-download`, and `strict-offline` embedding profile configurations, backed by a strict offline asset manifest registry that validates checksums and licenses.
8
+ - **Compatibility Fingerprints**: Implemented deterministic fingerprint extraction for repository scopes, capturing primary languages, frameworks, ORMs, and lockfile-resolved (npm, pnpm, yarn) dependency major versions, with monorepo workspace package support.
9
+ - **Portability Scoring and Bands**: Created a scorecard combining fingerprint, path, and task family similarity with prior reuse evidence. Classifies cross-repo candidates into portability bands (`validated_portable`, `same_family`, `weakly_related`, `incompatible`) with strict framework SemVer major-version penalties.
10
+ - **Cross-Repository Intervention Governance**: Enabled progressive delivery where `same_family` candidates are limited to conservative prompt delivery, `weakly_related` remain record-only, and `incompatible` are skipped.
11
+ - **Causal Trajectory Attribution**: Built a compiler that normalizes tool names/arguments and redacts volatile tokens (temp paths, UUIDs, branch names) to check timelines against compiled expectations (`recommended_steps` and `avoid_steps`). Yields detailed verdicts (`adoption_detected`, `non_adoption_detected`, `contra_adoption_detected`, etc.).
12
+ - **Quarantine Shadow-Probe Lifecycle**: Expired quarantine leases now transition candidates to a `shadow_probe` state. These are withheld from live prompt injection but evaluated as diagnostic candidates, restoring to `conservative` only after accumulating bounded no-harm passes in matching tasks, or retiring/re-quarantining on repeated harm.
13
+ - **Enhanced Diagnostics and Operator Surfaces**:
14
+ - Extended `ee doctor` to report embedding profile type, manifest checksum health, and offline asset readiness.
15
+ - Extended `ee inspect` with verbose output showing compatibility fingerprint summaries, SemVer penalties, causal trajectory verdicts with matched/violated expectations, and quarantine lease/shadow-probe histories.
16
+ - Updated README, README.zh-CN, and `docs/user-guide.md` with complete architecture and operator documentation.
17
+
18
+ ## Boundaries
19
+
20
+ - **No Blind Cross-Repo Injection**: Tech-stack similarity alone never unlocks direct eligible prompt injection for cross-repo candidates.
21
+ - **Strict Shadow-Probe Isolation**: Shadow-probe nodes remain completely excluded from live prompt injection; they accumulate no-harm passes solely via record-only diagnostic evaluations.
22
+ - **Avoid-Step Defaults**: Avoid-step violations default to non-adoption (`non_adoption_detected` or `contra_adoption_detected`) rather than automatically triggering a causal harm verdict, unless causal failure is explicitly observed.
23
+ - **Offline Integrity**: Strict offline profiles fail loudly on missing or corrupt assets, preventing silent online fallbacks unless explicitly allowed.
24
+
25
+ ## Validation
26
+
27
+ - Comprehensive unit and integration test coverage for embedding profiles, vector migration, fingerprinting, portability scoring, trajectory compilation, causal matches, quarantine leases, shadow-probes, and CLI diagnostics.
28
+ - Validation checks completed successfully:
29
+ - `pnpm exec tsc --noEmit`
30
+ - `pnpm exec vitest run`
31
+ - `pnpm exec openspec validate add-governed-portable-experience --strict`
32
+ - `pnpm check`
33
+ - `npm pack --dry-run`
34
+ - Real-host validation completed for:
35
+ - WSL Codex CLI lifecycle wrapper and persistence.
36
+ - Claude Code MCP wiring and `experienceengine_get_capabilities` tool invocation with `nvidia/nemotron-3-super-120b-a12b:free`.
37
+ - WSL OpenClaw plugin wiring after `ee repair openclaw`, with live high-confidence scenario writeback using `openrouter/nvidia/nemotron-3-super-120b-a12b:free`.
38
+ - Known host boundary:
39
+ - Windows Codex App validation was blocked by the local WindowsApps `codex.exe` shim returning `EPERM` / `Access is denied`; WSL Codex CLI validation passed.
@@ -0,0 +1,22 @@
1
+ # ExperienceEngine v0.4.1
2
+
3
+ `v0.4.1` is a focused Antigravity integration follow-up release.
4
+
5
+ ## What Changed
6
+
7
+ - Validated Antigravity Agent Desktop, `agy` CLI, and Antigravity IDE as user-level ExperienceEngine surfaces.
8
+ - Updated Antigravity diagnostics so `ee doctor antigravity` reports IDE hooks through the shared global Antigravity plugin surface when observed.
9
+ - Filtered Antigravity CLI hook events that only report CLI flags such as `--dangerously-skip-permissions` as the prompt, preventing noisy prompt-time and finalization task runs when no real user prompt can be resolved.
10
+
11
+ ## Validation
12
+
13
+ - `pnpm exec vitest run tests/unit/antigravity-hook.test.ts tests/unit/agy-exec-command.test.ts tests/unit/antigravity-global-wiring.test.ts tests/unit/doctor-command.test.ts`
14
+ - `pnpm exec tsc --noEmit --pretty false`
15
+ - `pnpm build`
16
+ - `pnpm exec openspec validate add-antigravity-adapter-integration --strict`
17
+ - `npm pack --dry-run`
18
+ - Real-host Antigravity validation for Agent Desktop, `agy` CLI, and IDE hook observation.
19
+
20
+ ## Known Boundary
21
+
22
+ - Full parallel Vitest runs can still show unrelated OpenClaw pack-test timing variance on Windows; the affected OpenClaw test file passes when rerun directly.
@@ -117,8 +117,16 @@ Install ExperienceEngine through the host setup flow for:
117
117
  - `/plugin install experienceengine@experienceengine`
118
118
  - `ee install claude-code` remains the explicit operator fallback when you need direct hooks + MCP wiring outside the marketplace flow
119
119
  - after installation, start a new Claude Code session so the plugin hooks and bundled MCP config are loaded
120
+ - `Google Antigravity`
121
+ - EE-managed setup:
122
+ - `ee install antigravity`
123
+ - validated headless CLI run:
124
+ - `ee agy exec -C <project-path> "<prompt>"`
125
+ - explicit Agent Desktop project activation:
126
+ - `ee antigravity activate-project -C <project-path>`
127
+ - after the managed path, start Antigravity Agent Desktop in an activated project or use `ee agy exec -C <project-path>` so the `.mcp.json` MCP configuration and `.agents/hooks.json` lifecycle hooks are loaded
120
128
 
121
- Across all three hosts, the intended product journey is the same:
129
+ Across all hosts, the intended product journey is the same:
122
130
 
123
131
  1. install ExperienceEngine through the host-specific setup path
124
132
  2. initialize shared ExperienceEngine state with `ee init`
@@ -146,13 +154,13 @@ OpenClaw also supports these additional phase-2 routine questions in-session:
146
154
  - "Is ExperienceEngine still warming up in this repo?"
147
155
  - "Why didn't ExperienceEngine inject anything just now?"
148
156
 
149
- For `OpenClaw`, `Codex`, and `Claude Code`, these routine follow-ups should stay in the host session first.
157
+ For `OpenClaw`, `Codex`, `Claude Code`, and `Google Antigravity`, these routine follow-ups should stay in the host session first.
150
158
 
151
159
  Use the `ee` CLI only when you need explicit validation, repair, or operator-style troubleshooting:
152
160
 
153
161
  ```bash
154
162
  ee init
155
- ee doctor <openclaw|claude-code|codex>
163
+ ee doctor <openclaw|claude-code|codex|antigravity>
156
164
  ee status
157
165
  ```
158
166
 
@@ -366,6 +374,40 @@ ee maintenance governance drain --cwd /path/to/repo
366
374
 
367
375
  That command is for explicit operator troubleshooting or catch-up. It uses the same scheduler, lease, validator, audit, and rollback snapshot path as host-attached governance. An optional keeper can wake the same drain path for stricter wall-clock schedules, but it does not bypass budgets, leases, deterministic validators, guarded execution rules, or rollback safeguards.
368
376
 
377
+ ## Governed Portable Experience
378
+
379
+ ExperienceEngine connects retrieval, attribution, and lifecycle layers to support governed, cautious sharing of experience nodes across different repositories and scopes.
380
+
381
+ ### Portability Bands & SemVer Compatibility
382
+
383
+ When retrieving experience candidates for a task, ExperienceEngine calculates a cross-repository compatibility scorecard. This scorecard determines how safe the guidance is in the current environment using the following **Portability Bands**:
384
+ - `validated_portable`: Highly compatible. The node matches the local programming language, and any shared dependencies have verified SemVer compatibility.
385
+ - `cautiously_portable`: Medium compatibility. Reused with caution, usually limited to conservative delivery state until local execution success is demonstrated.
386
+ - `incompatible`: The node requires frameworks or languages not present in the current project. Delivery is blocked.
387
+
388
+ Compatibility scoring factors in **SemVer matching penalties**:
389
+ - Framework or dependency version mismatches subtract penalty points (e.g. minor or major version drift).
390
+ - Language mismatches (e.g., trying to use Python guidance in a TypeScript codebase) flag the node as incompatible.
391
+
392
+ ### Causal Trajectory Attribution
393
+
394
+ During post-task finalization, ExperienceEngine verifies if the host agent actually adopted the expectations of an injected hint. This **Causal Trajectory Attribution** produces a precise verdict:
395
+ - `adoption_detected`: The agent successfully matched the expectations of the injected hint (e.g., specific file modifications or CLI tool executions).
396
+ - `non_adoption_detected`: The agent completed the task but did not follow the suggested guidance.
397
+ - `unverifiable`: The task ended in failure, or outcomes could not be traced clearly.
398
+
399
+ These trajectory verdicts prevent false positives in outcome attribution, ensuring that helpfulness or harm is only counted if the agent actually used the guidance.
400
+
401
+ ### Quarantine Leases & Shadow-Probe Release
402
+
403
+ To ensure quarantined nodes have a safe path back to eligibility without erasing historical lessons:
404
+ 1. **Quarantine Leases**: When a node is quarantined due to harm or invalidation, it is given a lease duration.
405
+ 2. **Lease Expiration**: Once the lease expires, the node is transitioned to a special `shadow_probe` delivery state.
406
+ 3. **Shadow Probe**: While in `shadow_probe`, the node is evaluated silently behind the scenes. If the agent finishes tasks using this guidance without any new harm, a **no-harm pass counter** is incremented.
407
+ 4. **Conservative Restoration**: Upon successfully passing the shadow probe, the node is restored to `conservative_only` delivery (rather than direct live eligibility).
408
+ 5. **Repeated-Harm Retirement**: If the node causes repeated harm during its shadow probe or live recovery, it is permanently retired.
409
+ 6. **Preservation of History**: Throughout this cycle, historical helped/harmed counts, original delivery states, and release attempt logs are strictly preserved.
410
+
369
411
  ## How MCP Interaction Works
370
412
 
371
413
  For `Codex` and `Claude Code`, ExperienceEngine is designed to keep routine review and management inside the host session first.
@@ -531,6 +573,13 @@ Notes:
531
573
  - the recommended registry for managed model downloads is `https://registry.npmjs.org`
532
574
  - `ee doctor ...` reports a first-value readiness summary so users can see how much captured evidence exists before the first durable node is promoted
533
575
 
576
+ ### Offline Profiles, Manifest Health, and Vector Migration
577
+
578
+ For air-gapped or sensitive environments, ExperienceEngine supports fully offline semantic retrieval:
579
+ - **Offline Profiles**: Set `embeddingProvider = "local"` and configure an offline profile (such as `strict-offline`) in settings. ExperienceEngine will rely entirely on local ONNX model assets.
580
+ - **Manifest Health Verification**: When running `ee doctor`, the system validates the health of the local offline profile. It reads the model manifest files, checks checksums, and detects corrupted assets. If a strict-offline profile is active but files are missing or corrupt, a warning is raised automatically.
581
+ - **Vector Migration**: Upgrading embedding models or altering dimensions requires vector migration. ExperienceEngine tracks vector migration status for every node (`migrated`, `pending`, etc.) along with timestamps and migration errors. You can inspect this status via `ee inspect node:<id>` or `ee doctor`.
582
+
534
583
  Maintenance:
535
584
 
536
585
  ```bash
@@ -694,6 +743,70 @@ Diagnostics note:
694
743
  - WSL Codex CLI must have its own MCP registration in the WSL Codex home; it can still reuse the same repo `.codex/hooks.json`
695
744
  - on WSL, `ee doctor codex` also warns when `codex` resolves to a WindowsApps shim instead of the Linux Codex CLI
696
745
 
746
+ ### Google Antigravity Advanced Commands
747
+
748
+ Antigravity has multiple product entries. ExperienceEngine's current `antigravity` adapter targets **Antigravity Agent Desktop** and the standalone **Antigravity CLI (`agy`)**. It does not adapt the separate Antigravity IDE shell. EE data remains user-level under the configured ExperienceEngine home, while project experience is isolated by project scope. Antigravity uses user-level plugin and MCP configuration by default; project `.mcp.json` and `.agents/hooks.json` activation remains available as a fallback.
749
+
750
+ Explicit host install:
751
+
752
+ ```bash
753
+ ee install antigravity
754
+ ```
755
+
756
+ What happens:
757
+ - ExperienceEngine records user-level Antigravity adapter state under the configured ExperienceEngine home.
758
+ - By default, it installs user-level Antigravity plugin wiring for Agent Desktop and `agy` CLI, plus global Agent Desktop MCP configuration.
759
+ - It does not need to activate each new Agent Desktop project after user-level install. If global plugin loading is unavailable or needs recovery, use the project activation fallback.
760
+ - The hook contract spike still runs before hook installation; if it fails, installation falls back to `mcp_only`. Use `--mcp-only` when you intentionally want only the MCP inspection/control surface.
761
+ - All command paths in user-level `hooks.json` and `mcp_config.json` are registered using absolute paths resolved via `packageRoot` for portability.
762
+ - Antigravity supports both stdio MCP calls and an advanced artifact-assisted analyzer that automatically parses planning and verification markdown files (`task.md`, `walkthrough.md`, `implementation_plan.md`) to reconstruct outcomes and check off completed tasks.
763
+ - The installation ends with a short cold-start note so users know capture is active before the first formal hint appears.
764
+
765
+ Local state changes:
766
+ - user-level ExperienceEngine adapter state under `~/.experienceengine`
767
+ - Agent Desktop plugin under `~/.gemini/config/plugins/experienceengine`
768
+ - Antigravity CLI plugin under `~/.gemini/antigravity-cli/plugins/experienceengine`
769
+ - Agent Desktop MCP config under `~/.gemini/antigravity/mcp_config.json`
770
+ - fallback project MCP config in `.mcp.json` only when `ee antigravity activate-project -C <project-path>` or a compatibility path writes it
771
+ - fallback project hooks config in `.agents/hooks.json` only when project activation is used
772
+
773
+ Useful commands:
774
+
775
+ ```bash
776
+ ee doctor antigravity
777
+ ee repair antigravity
778
+ ee upgrade antigravity
779
+ ee antigravity activate-project -C <project-path>
780
+ ee agy exec -C <project-path> "<prompt>"
781
+ ```
782
+
783
+ First validation:
784
+
785
+ ```bash
786
+ ee doctor antigravity
787
+ ```
788
+
789
+ Success looks like:
790
+ - doctor reports the adapter as installed and healthy.
791
+ - global plugin/MCP files are created with the correct configurations and paths.
792
+ - Antigravity Agent Desktop loads the MCP server successfully and can call an ExperienceEngine MCP tool such as `experienceengine_get_capabilities`.
793
+ - `ee agy exec -C <project-path>` loads the user-level plugin hooks in headless CLI mode while still supplying `--add-dir` for reliable workspace discovery.
794
+
795
+ Validated CLI invocation:
796
+
797
+ ```bash
798
+ ee agy exec -C <project-path> "<prompt>"
799
+ ```
800
+
801
+ Host note:
802
+ - The Antigravity IDE application is tracked as a separate surface. `ee doctor antigravity` reports the IDE command, whether an IDE MCP tool cache has been observed under `~/.gemini/antigravity-ide/mcp/experienceengine`, and whether IDE hooks are observed through the shared global plugin surface. Real-host validation showed the IDE loads `~/.gemini/config/plugins/experienceengine/hooks.json` for lifecycle hooks while storing its MCP tool cache under the IDE-specific state directory.
803
+ - The PATH-visible `antigravity` command may point to the separate IDE shell. `ee doctor antigravity` reports that command separately and uses `agy` for CLI availability.
804
+ - `ee agy exec -C <project>` invokes `agy --add-dir <project>` internally because direct `agy` workspace discovery can fail on Windows when symlink creation is unavailable.
805
+ - CLI/operator commands such as `ee install antigravity`, `ee doctor antigravity`, and `ee repair antigravity` configure and inspect user-level adapter state plus global plugin/MCP wiring. `ee antigravity activate-project -C <project>` remains the fallback for project-local MCP and hook wiring.
806
+ - ExperienceEngine installs relative-path hooks for prompt-time guidance (`PreInvocation`), tool-use allow/capture (`PreToolUse`, `PostToolUse`), and session-end finalization (`Stop`).
807
+ - To prevent infinite loops during preinvocation, the hook mutations are structured to gate execution per session ID, ensuring safe one-time injection per prompt context.
808
+ - If Antigravity says hooks are misconfigured or MCP registration is missing, run `ee repair antigravity`.
809
+
697
810
  Developer source-repo host validation lives at:
698
811
 
699
812
  - [docs/development/source-repo-host-validation.md](development/source-repo-host-validation.md)
@@ -706,6 +819,9 @@ Source-repo host validation matrix:
706
819
  | WSL Codex CLI | Validated | WSL `codex exec` with shared `.codex/hooks.json` writes to the same ExperienceEngine home and `scope_id` as Windows Codex App. |
707
820
  | Claude Code on Windows | Validated | Real hooks fired `UserPromptSubmit`, `PreToolUse`, `PostToolUse`, and `SessionEnd`; `SessionEnd` drained through the background queue and wrote to the shared project scope. |
708
821
  | OpenClaw on WSL | Validated | WSL OpenClaw gateway loaded the current ExperienceEngine plugin and wrote task runs to the shared ExperienceEngine home. ExperienceEngine now resolves the real project root from OpenClaw hook payloads or nearby repo markers before scope resolution. If OpenClaw only reports its global workspace, ExperienceEngine isolates that session instead of reusing unrelated global-workspace experience. OpenClaw validated with `openrouter/tencent/hy3-preview:free`; the bare `tencent/hy3-preview:free` id is marked missing by OpenClaw's model registry. |
822
+ | Google Antigravity Agent Desktop on Windows | Validated global plugin wiring | Real Agent Desktop loaded user-level plugin hooks; MCP `experienceengine_get_capabilities` was callable; real hooks fired `PreInvocation`, `PreToolUse`, `PostToolUse`, and `Stop`; `PreToolUse` accepted `{ "decision": "allow" }`; task runs wrote to the shared project scope without project-local `.mcp.json` or `.agents/hooks.json`. |
823
+ | Antigravity CLI (`agy`) on Windows | Validated with `--add-dir`; wrapper added | `agy --add-dir <project-path> --print --dangerously-skip-permissions --print-timeout 5m "<prompt>"` loaded hooks and wrote task runs to the shared project scope. Direct project auto-discovery without `--add-dir` can fail when Windows symlink creation is not permitted, so users should prefer `ee agy exec -C <project>`. |
824
+ | Antigravity IDE on Windows | Validated global plugin hooks | Real IDE Agent loaded `~/.gemini/config/plugins/experienceengine/hooks.json`, fired `PreInvocation`, `PreToolUse`, `PostToolUse`, and `Stop`, and wrote task runs to the shared project scope. IDE MCP tool cache files are stored under `~/.gemini/antigravity-ide/mcp/experienceengine`; no IDE-specific EE plugin directory is required for validated hooks. |
709
825
 
710
826
  This matrix is source-repo validation only. Published npm package validation and host-native marketplace validation must be called out separately during release preparation.
711
827
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "experienceengine",
3
3
  "name": "ExperienceEngine",
4
- "version": "0.3.6",
4
+ "version": "0.4.0",
5
5
  "description": "Context-aware experience intervention controller for coding and debugging tasks.",
6
6
  "configSchema": {
7
7
  "type": "object",