xytara 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +5 -1
- package/ADAPTER_START_HERE.md +56 -0
- package/CARRIED_HANDOFF_DEMO.md +60 -0
- package/EXAMPLE_PATHS.md +53 -0
- package/OPERATIONS_RUNBOOK.md +65 -0
- package/OPERATOR_START_HERE.md +63 -0
- package/PARTNER_READY_PATH.md +71 -0
- package/PROGRAM_COMPLETE_RELEASE.md +63 -0
- package/PROGRAM_STATUS.md +57 -0
- package/PUBLIC_DEMO_SCRIPT.md +78 -0
- package/PUBLISH_PLAN.md +7 -5
- package/README.md +66 -0
- package/RELEASE_CHECKLIST.md +8 -2
- package/RELEASE_NOTES.md +12 -3
- package/START_HERE.md +32 -0
- package/SUPABASE_RUNTIME_STATE_SETUP.md +61 -0
- package/WHY_XYTARA_XOONYA.md +63 -0
- package/adapters/examples/minimal-third-party-execution-adapter.js +61 -0
- package/adapters/examples/minimal-third-party-execution-adapter.manifest.json +79 -0
- package/adapters/examples/minimal-third-party-execution-registration.record.json +26 -0
- package/adapters/examples/minimal-third-party-execution.certification-pack.json +22 -0
- package/adapters/examples/minimal-third-party-execution.submission-bundle.json +126 -0
- package/bin/xytara-release.js +1251 -1
- package/examples/adapter_review_walkthrough.js +53 -0
- package/examples/export_carried_handoff.js +80 -0
- package/examples/funded_runtime_walkthrough.js +70 -0
- package/examples/partner_launch_walkthrough.js +43 -0
- package/examples/quickstart.js +3255 -0
- package/index.js +7 -1
- package/lib/adapter_pack.js +118 -0
- package/lib/adapter_partner_pack.js +89 -0
- package/lib/adapter_promotion_pack.js +89 -0
- package/lib/outreach_copy_pack.js +51 -0
- package/lib/outreach_message_pack.js +71 -0
- package/lib/outreach_target_pack.js +60 -0
- package/lib/phase_10_closeout_pack.js +45 -0
- package/lib/phase_10_completion_pack.js +76 -0
- package/lib/phase_10_decision_record_pack.js +54 -0
- package/lib/phase_10_decision_resolution_pack.js +53 -0
- package/lib/phase_10_demand_signal_adapters_runtime_pack.js +74 -0
- package/lib/phase_10_ecosystem_backlog_triage_runtime_pack.js +74 -0
- package/lib/phase_10_freeze_baseline_pack.js +67 -0
- package/lib/phase_10_freeze_review_pack.js +64 -0
- package/lib/phase_10_gate_pack.js +57 -0
- package/lib/phase_10_long_tail_continuity_pack.js +80 -0
- package/lib/phase_10_long_tail_ecosystem_pack.js +66 -0
- package/lib/phase_10_niche_extension_registry_runtime_pack.js +74 -0
- package/lib/phase_1_claude_mcp_pack.js +60 -0
- package/lib/phase_1_claude_mcp_runtime_pack.js +52 -0
- package/lib/phase_1_ecosystem_pack.js +67 -0
- package/lib/phase_1_openai_codex_pack.js +60 -0
- package/lib/phase_1_openai_codex_runtime_pack.js +52 -0
- package/lib/phase_2_base_runtime_pack.js +71 -0
- package/lib/phase_2_base_usdc_runtime_pack.js +72 -0
- package/lib/phase_2_closeout_pack.js +65 -0
- package/lib/phase_2_completion_pack.js +113 -0
- package/lib/phase_2_decision_record_pack.js +66 -0
- package/lib/phase_2_decision_resolution_pack.js +69 -0
- package/lib/phase_2_eth_runtime_pack.js +70 -0
- package/lib/phase_2_evm_base_runtime_pack.js +73 -0
- package/lib/phase_2_evm_runtime_pack.js +71 -0
- package/lib/phase_2_flip_preview_pack.js +60 -0
- package/lib/phase_2_freeze_review_pack.js +99 -0
- package/lib/phase_2_gate_pack.js +77 -0
- package/lib/phase_2_payment_rails_pack.js +71 -0
- package/lib/phase_2_usdc_runtime_pack.js +71 -0
- package/lib/phase_3_brc_runtime_pack.js +81 -0
- package/lib/phase_3_bsv_teranode_runtime_pack.js +83 -0
- package/lib/phase_3_closeout_pack.js +62 -0
- package/lib/phase_3_completion_pack.js +94 -0
- package/lib/phase_3_decision_record_pack.js +64 -0
- package/lib/phase_3_decision_resolution_pack.js +69 -0
- package/lib/phase_3_freeze_baseline_pack.js +67 -0
- package/lib/phase_3_freeze_review_pack.js +80 -0
- package/lib/phase_3_gate_pack.js +76 -0
- package/lib/phase_3_metanet_runtime_pack.js +81 -0
- package/lib/phase_3_native_bsv_pack.js +91 -0
- package/lib/phase_3_native_continuity_pack.js +82 -0
- package/lib/phase_4_attestation_runtime_pack.js +75 -0
- package/lib/phase_4_closeout_pack.js +45 -0
- package/lib/phase_4_completion_pack.js +94 -0
- package/lib/phase_4_decision_record_pack.js +54 -0
- package/lib/phase_4_decision_resolution_pack.js +45 -0
- package/lib/phase_4_erc8004_runtime_pack.js +76 -0
- package/lib/phase_4_freeze_baseline_pack.js +67 -0
- package/lib/phase_4_freeze_review_pack.js +68 -0
- package/lib/phase_4_gate_pack.js +58 -0
- package/lib/phase_4_identity_registry_runtime_pack.js +75 -0
- package/lib/phase_4_identity_trust_pack.js +73 -0
- package/lib/phase_4_trust_continuity_pack.js +86 -0
- package/lib/phase_5_antelope_runtime_pack.js +76 -0
- package/lib/phase_5_closeout_pack.js +44 -0
- package/lib/phase_5_completion_pack.js +82 -0
- package/lib/phase_5_decision_record_pack.js +54 -0
- package/lib/phase_5_decision_resolution_pack.js +45 -0
- package/lib/phase_5_freeze_baseline_pack.js +67 -0
- package/lib/phase_5_freeze_review_pack.js +68 -0
- package/lib/phase_5_gate_pack.js +58 -0
- package/lib/phase_5_major_rails_continuity_pack.js +86 -0
- package/lib/phase_5_major_rails_pack.js +74 -0
- package/lib/phase_5_proton_xpr_runtime_pack.js +76 -0
- package/lib/phase_5_solana_runtime_pack.js +76 -0
- package/lib/phase_6_autogen_runtime_pack.js +72 -0
- package/lib/phase_6_closeout_pack.js +46 -0
- package/lib/phase_6_completion_pack.js +77 -0
- package/lib/phase_6_decision_record_pack.js +54 -0
- package/lib/phase_6_decision_resolution_pack.js +53 -0
- package/lib/phase_6_framework_continuity_pack.js +81 -0
- package/lib/phase_6_framework_runtime_pack.js +68 -0
- package/lib/phase_6_freeze_baseline_pack.js +68 -0
- package/lib/phase_6_freeze_review_pack.js +65 -0
- package/lib/phase_6_gate_pack.js +59 -0
- package/lib/phase_6_langchain_runtime_pack.js +72 -0
- package/lib/phase_6_langgraph_runtime_pack.js +72 -0
- package/lib/phase_6_semantic_kernel_runtime_pack.js +72 -0
- package/lib/phase_7_closeout_pack.js +45 -0
- package/lib/phase_7_completion_pack.js +85 -0
- package/lib/phase_7_decision_record_pack.js +53 -0
- package/lib/phase_7_decision_resolution_pack.js +53 -0
- package/lib/phase_7_event_system_continuity_pack.js +89 -0
- package/lib/phase_7_event_system_pack.js +76 -0
- package/lib/phase_7_freeze_baseline_pack.js +74 -0
- package/lib/phase_7_freeze_review_pack.js +65 -0
- package/lib/phase_7_gate_pack.js +58 -0
- package/lib/phase_7_kafka_runtime_pack.js +74 -0
- package/lib/phase_7_mqtt_runtime_pack.js +74 -0
- package/lib/phase_7_nats_runtime_pack.js +74 -0
- package/lib/phase_7_webhook_event_bus_runtime_pack.js +74 -0
- package/lib/phase_8_closeout_pack.js +46 -0
- package/lib/phase_8_completion_pack.js +82 -0
- package/lib/phase_8_decision_record_pack.js +54 -0
- package/lib/phase_8_decision_resolution_pack.js +53 -0
- package/lib/phase_8_external_receipt_import_runtime_pack.js +74 -0
- package/lib/phase_8_external_result_import_runtime_pack.js +74 -0
- package/lib/phase_8_freeze_baseline_pack.js +71 -0
- package/lib/phase_8_freeze_review_pack.js +64 -0
- package/lib/phase_8_gate_pack.js +58 -0
- package/lib/phase_8_proof_bridge_continuity_pack.js +86 -0
- package/lib/phase_8_proof_bridges_pack.js +72 -0
- package/lib/phase_8_proof_bundle_normalization_runtime_pack.js +74 -0
- package/lib/phase_9_closeout_pack.js +46 -0
- package/lib/phase_9_completion_pack.js +82 -0
- package/lib/phase_9_custody_refs_runtime_pack.js +74 -0
- package/lib/phase_9_decision_record_pack.js +54 -0
- package/lib/phase_9_decision_resolution_pack.js +53 -0
- package/lib/phase_9_freeze_baseline_pack.js +71 -0
- package/lib/phase_9_freeze_review_pack.js +64 -0
- package/lib/phase_9_gate_pack.js +58 -0
- package/lib/phase_9_operator_accounting_bridges_runtime_pack.js +74 -0
- package/lib/phase_9_treasury_connectivity_pack.js +72 -0
- package/lib/phase_9_treasury_continuity_pack.js +86 -0
- package/lib/phase_9_treasury_destinations_runtime_pack.js +74 -0
- package/lib/phase_program_pack.js +120 -0
- package/lib/release_center.js +970 -0
- package/lib/release_history.js +1 -1
- package/lib/runtime_state_store.js +212 -27
- package/lib/soft_launch_pack.js +78 -0
- package/package.json +13 -1
- package/server.js +2055 -252
package/lib/release_history.js
CHANGED
|
@@ -11,7 +11,7 @@ function buildReleaseHistory() {
|
|
|
11
11
|
release_track: "public_release",
|
|
12
12
|
history: [
|
|
13
13
|
{
|
|
14
|
-
version: "2.
|
|
14
|
+
version: "2.2.0",
|
|
15
15
|
channel: "public_release",
|
|
16
16
|
maturity_posture: "launch_ready",
|
|
17
17
|
headline: "public machine-commerce release-candidate with release-center, announcement, and candidate rehearsal surfaces",
|
|
@@ -8,6 +8,16 @@ function normalizeFilePath(filePath) {
|
|
|
8
8
|
return raw ? path.resolve(raw) : "";
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
function normalizeUrl(url) {
|
|
12
|
+
const raw = typeof url === "string" ? url.trim() : "";
|
|
13
|
+
return raw ? raw.replace(/\/+$/, "") : "";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function normalizeString(value, fallback = "") {
|
|
17
|
+
const raw = typeof value === "string" ? value.trim() : "";
|
|
18
|
+
return raw || fallback;
|
|
19
|
+
}
|
|
20
|
+
|
|
11
21
|
function serializeValue(value) {
|
|
12
22
|
if (value instanceof Map) {
|
|
13
23
|
return {
|
|
@@ -52,15 +62,27 @@ function deserializeValue(value) {
|
|
|
52
62
|
|
|
53
63
|
function createRuntimeStateStore(config = {}) {
|
|
54
64
|
const filePath = normalizeFilePath(config.filePath);
|
|
65
|
+
const directoryPath = filePath ? path.dirname(filePath) : "";
|
|
55
66
|
const intervalMs = Math.max(1000, Number.parseInt(String(config.intervalMs || 5000), 10) || 5000);
|
|
67
|
+
const supabaseUrl = normalizeUrl(config.supabaseUrl);
|
|
68
|
+
const supabaseServiceRoleKey = normalizeString(config.supabaseServiceRoleKey);
|
|
69
|
+
const supabaseTable = normalizeString(config.supabaseTable, "xytara_runtime_state");
|
|
70
|
+
const stateKey = normalizeString(config.stateKey, "default");
|
|
71
|
+
const storageMode = supabaseUrl && supabaseServiceRoleKey ? "supabase" : filePath ? "file" : "memory";
|
|
56
72
|
let dirty = false;
|
|
57
73
|
let timer = null;
|
|
58
74
|
let lastPersistedAtIso = null;
|
|
59
75
|
let lastFlushSucceeded = false;
|
|
60
76
|
let lastError = null;
|
|
77
|
+
let snapshotExists = false;
|
|
78
|
+
let snapshotUpdatedAtIso = null;
|
|
79
|
+
let snapshotSizeBytes = 0;
|
|
80
|
+
let remoteConfigured = storageMode === "supabase";
|
|
81
|
+
let remoteReachable = storageMode !== "supabase";
|
|
82
|
+
let remoteTableReady = storageMode !== "supabase";
|
|
61
83
|
|
|
62
84
|
function enabled() {
|
|
63
|
-
return
|
|
85
|
+
return storageMode !== "memory";
|
|
64
86
|
}
|
|
65
87
|
|
|
66
88
|
function markDirty() {
|
|
@@ -68,84 +90,246 @@ function createRuntimeStateStore(config = {}) {
|
|
|
68
90
|
dirty = true;
|
|
69
91
|
}
|
|
70
92
|
|
|
71
|
-
function
|
|
72
|
-
if (!
|
|
93
|
+
function applyRestoredState(state, restored) {
|
|
94
|
+
if (!restored || typeof restored !== "object" || !state) return false;
|
|
95
|
+
for (const key of Object.keys(state)) {
|
|
96
|
+
if (Object.prototype.hasOwnProperty.call(restored, key)) {
|
|
97
|
+
state[key] = restored[key];
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function inspectFileDirectory() {
|
|
104
|
+
let exists = false;
|
|
105
|
+
let writable = false;
|
|
106
|
+
let error = null;
|
|
107
|
+
if (storageMode !== "file") {
|
|
108
|
+
return {
|
|
109
|
+
exists: false,
|
|
110
|
+
writable: false,
|
|
111
|
+
error: null
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
exists = fs.existsSync(directoryPath);
|
|
116
|
+
if (exists) {
|
|
117
|
+
fs.accessSync(directoryPath, fs.constants.W_OK);
|
|
118
|
+
writable = true;
|
|
119
|
+
}
|
|
120
|
+
} catch (issue) {
|
|
121
|
+
writable = false;
|
|
122
|
+
error = issue;
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
exists,
|
|
126
|
+
writable,
|
|
127
|
+
error
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async function fetchSupabase(pathname, options = {}) {
|
|
132
|
+
const response = await fetch(`${supabaseUrl}${pathname}`, {
|
|
133
|
+
...options,
|
|
134
|
+
headers: {
|
|
135
|
+
apikey: supabaseServiceRoleKey,
|
|
136
|
+
authorization: `Bearer ${supabaseServiceRoleKey}`,
|
|
137
|
+
...(options.headers || {})
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
remoteReachable = true;
|
|
141
|
+
if (!response.ok) {
|
|
142
|
+
const text = await response.text();
|
|
143
|
+
const error = new Error(`supabase_runtime_state_${response.status}: ${text || response.statusText}`);
|
|
144
|
+
error.status = response.status;
|
|
145
|
+
throw error;
|
|
146
|
+
}
|
|
147
|
+
return response;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function updateSuccessSnapshotMetadata(persistedAtIso, serializedSnapshot) {
|
|
151
|
+
lastPersistedAtIso = persistedAtIso;
|
|
152
|
+
lastFlushSucceeded = true;
|
|
153
|
+
lastError = null;
|
|
154
|
+
snapshotExists = true;
|
|
155
|
+
snapshotUpdatedAtIso = persistedAtIso;
|
|
156
|
+
snapshotSizeBytes = Buffer.byteLength(JSON.stringify(serializedSnapshot), "utf8");
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async function flushSupabase(state) {
|
|
160
|
+
if (!dirty || !state) return false;
|
|
161
|
+
const persistedAtIso = new Date().toISOString();
|
|
162
|
+
const serializedSnapshot = serializeValue(state);
|
|
163
|
+
const payload = [{
|
|
164
|
+
state_key: stateKey,
|
|
165
|
+
snapshot: serializedSnapshot,
|
|
166
|
+
persisted_at_iso: persistedAtIso
|
|
167
|
+
}];
|
|
168
|
+
try {
|
|
169
|
+
await fetchSupabase(`/rest/v1/${encodeURIComponent(supabaseTable)}?on_conflict=state_key`, {
|
|
170
|
+
method: "POST",
|
|
171
|
+
headers: {
|
|
172
|
+
"content-type": "application/json",
|
|
173
|
+
prefer: "resolution=merge-duplicates,return=minimal"
|
|
174
|
+
},
|
|
175
|
+
body: JSON.stringify(payload)
|
|
176
|
+
});
|
|
177
|
+
remoteTableReady = true;
|
|
178
|
+
dirty = false;
|
|
179
|
+
updateSuccessSnapshotMetadata(persistedAtIso, serializedSnapshot);
|
|
180
|
+
return true;
|
|
181
|
+
} catch (error) {
|
|
182
|
+
lastFlushSucceeded = false;
|
|
183
|
+
lastError = error;
|
|
184
|
+
remoteReachable = false;
|
|
185
|
+
remoteTableReady = false;
|
|
186
|
+
throw error;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function flushFile(state) {
|
|
191
|
+
if (!dirty || !state) return false;
|
|
73
192
|
try {
|
|
74
193
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
75
194
|
const tempPath = `${filePath}.tmp`;
|
|
195
|
+
const persistedAtIso = new Date().toISOString();
|
|
196
|
+
const serializedSnapshot = serializeValue(state);
|
|
76
197
|
const snapshot = {
|
|
77
|
-
persisted_at_iso:
|
|
78
|
-
state:
|
|
198
|
+
persisted_at_iso: persistedAtIso,
|
|
199
|
+
state: serializedSnapshot
|
|
79
200
|
};
|
|
80
201
|
fs.writeFileSync(tempPath, JSON.stringify(snapshot, null, 2), "utf8");
|
|
81
202
|
fs.renameSync(tempPath, filePath);
|
|
82
203
|
dirty = false;
|
|
83
|
-
|
|
204
|
+
updateSuccessSnapshotMetadata(persistedAtIso, serializedSnapshot);
|
|
205
|
+
return true;
|
|
206
|
+
} catch (error) {
|
|
207
|
+
lastFlushSucceeded = false;
|
|
208
|
+
lastError = error;
|
|
209
|
+
throw error;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async function flush(state) {
|
|
214
|
+
if (!enabled() || !dirty || !state) return false;
|
|
215
|
+
if (storageMode === "supabase") {
|
|
216
|
+
return flushSupabase(state);
|
|
217
|
+
}
|
|
218
|
+
if (storageMode === "file") {
|
|
219
|
+
return flushFile(state);
|
|
220
|
+
}
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
async function loadSupabase(state) {
|
|
225
|
+
try {
|
|
226
|
+
const response = await fetchSupabase(
|
|
227
|
+
`/rest/v1/${encodeURIComponent(supabaseTable)}?state_key=eq.${encodeURIComponent(stateKey)}&select=snapshot,persisted_at_iso&limit=1`
|
|
228
|
+
);
|
|
229
|
+
const rows = await response.json();
|
|
230
|
+
const row = Array.isArray(rows) && rows[0] ? rows[0] : null;
|
|
231
|
+
remoteTableReady = true;
|
|
232
|
+
if (!row || !row.snapshot) {
|
|
233
|
+
dirty = false;
|
|
234
|
+
lastFlushSucceeded = true;
|
|
235
|
+
lastError = null;
|
|
236
|
+
snapshotExists = false;
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
const restored = deserializeValue(row.snapshot);
|
|
240
|
+
const applied = applyRestoredState(state, restored);
|
|
241
|
+
dirty = false;
|
|
242
|
+
lastPersistedAtIso = row.persisted_at_iso ? String(row.persisted_at_iso) : null;
|
|
84
243
|
lastFlushSucceeded = true;
|
|
85
244
|
lastError = null;
|
|
86
|
-
|
|
245
|
+
snapshotExists = applied;
|
|
246
|
+
snapshotUpdatedAtIso = lastPersistedAtIso;
|
|
247
|
+
snapshotSizeBytes = Buffer.byteLength(JSON.stringify(row.snapshot), "utf8");
|
|
248
|
+
return applied;
|
|
87
249
|
} catch (error) {
|
|
88
250
|
lastFlushSucceeded = false;
|
|
89
251
|
lastError = error;
|
|
252
|
+
remoteReachable = false;
|
|
253
|
+
remoteTableReady = false;
|
|
90
254
|
throw error;
|
|
91
255
|
}
|
|
92
256
|
}
|
|
93
257
|
|
|
94
|
-
function
|
|
95
|
-
if (!
|
|
258
|
+
async function loadFile(state) {
|
|
259
|
+
if (!state || !fs.existsSync(filePath)) return false;
|
|
96
260
|
const raw = fs.readFileSync(filePath, "utf8");
|
|
97
261
|
const parsed = JSON.parse(raw);
|
|
98
262
|
const restored = deserializeValue(parsed && parsed.state ? parsed.state : parsed);
|
|
99
|
-
|
|
100
|
-
for (const key of Object.keys(state)) {
|
|
101
|
-
if (Object.prototype.hasOwnProperty.call(restored, key)) {
|
|
102
|
-
state[key] = restored[key];
|
|
103
|
-
}
|
|
104
|
-
}
|
|
263
|
+
const applied = applyRestoredState(state, restored);
|
|
105
264
|
dirty = false;
|
|
106
265
|
lastPersistedAtIso = parsed && parsed.persisted_at_iso ? String(parsed.persisted_at_iso) : null;
|
|
107
266
|
lastFlushSucceeded = true;
|
|
108
267
|
lastError = null;
|
|
109
|
-
|
|
268
|
+
snapshotExists = applied;
|
|
269
|
+
snapshotUpdatedAtIso = parsed && parsed.persisted_at_iso ? String(parsed.persisted_at_iso) : null;
|
|
270
|
+
snapshotSizeBytes = Buffer.byteLength(raw, "utf8");
|
|
271
|
+
return applied;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
async function load(state) {
|
|
275
|
+
if (!enabled() || !state) return false;
|
|
276
|
+
if (storageMode === "supabase") {
|
|
277
|
+
return loadSupabase(state);
|
|
278
|
+
}
|
|
279
|
+
if (storageMode === "file") {
|
|
280
|
+
return loadFile(state);
|
|
281
|
+
}
|
|
282
|
+
return false;
|
|
110
283
|
}
|
|
111
284
|
|
|
112
285
|
function inspect() {
|
|
113
|
-
const
|
|
114
|
-
const
|
|
286
|
+
const fileDirectory = inspectFileDirectory();
|
|
287
|
+
const fileStats = storageMode === "file" && snapshotExists && fs.existsSync(filePath)
|
|
288
|
+
? fs.statSync(filePath)
|
|
289
|
+
: null;
|
|
115
290
|
return {
|
|
116
291
|
enabled: enabled(),
|
|
292
|
+
storage_mode: storageMode,
|
|
117
293
|
file_path: filePath || null,
|
|
294
|
+
directory_path: directoryPath || null,
|
|
118
295
|
interval_ms: intervalMs,
|
|
119
296
|
dirty,
|
|
120
297
|
timer_active: Boolean(timer),
|
|
298
|
+
directory_exists: storageMode === "file" ? fileDirectory.exists : false,
|
|
299
|
+
directory_writable: storageMode === "file" ? fileDirectory.writable : false,
|
|
300
|
+
directory_error: storageMode === "file" && fileDirectory.error ? fileDirectory.error.message : null,
|
|
121
301
|
snapshot_exists: snapshotExists,
|
|
122
|
-
snapshot_size_bytes:
|
|
123
|
-
snapshot_updated_at_iso:
|
|
302
|
+
snapshot_size_bytes: fileStats ? fileStats.size : snapshotSizeBytes,
|
|
303
|
+
snapshot_updated_at_iso: fileStats ? fileStats.mtime.toISOString() : snapshotUpdatedAtIso,
|
|
124
304
|
last_persisted_at_iso: lastPersistedAtIso,
|
|
125
305
|
last_flush_succeeded: lastFlushSucceeded,
|
|
126
|
-
last_error: lastError ? lastError.message : null
|
|
306
|
+
last_error: lastError ? lastError.message : null,
|
|
307
|
+
supabase_url: supabaseUrl || null,
|
|
308
|
+
supabase_table: storageMode === "supabase" ? supabaseTable : null,
|
|
309
|
+
supabase_state_key: storageMode === "supabase" ? stateKey : null,
|
|
310
|
+
remote_configured: remoteConfigured,
|
|
311
|
+
remote_reachable: remoteReachable,
|
|
312
|
+
remote_table_ready: remoteTableReady
|
|
127
313
|
};
|
|
128
314
|
}
|
|
129
315
|
|
|
130
316
|
function start(state) {
|
|
131
317
|
if (!enabled() || timer) return;
|
|
132
318
|
timer = setInterval(() => {
|
|
133
|
-
|
|
134
|
-
flush(state);
|
|
135
|
-
} catch (error) {
|
|
319
|
+
Promise.resolve(flush(state)).catch((error) => {
|
|
136
320
|
console.error("runtime state snapshot flush failed", error);
|
|
137
|
-
}
|
|
321
|
+
});
|
|
138
322
|
}, intervalMs);
|
|
139
323
|
if (typeof timer.unref === "function") timer.unref();
|
|
140
324
|
}
|
|
141
325
|
|
|
142
|
-
function stop(state) {
|
|
326
|
+
async function stop(state) {
|
|
143
327
|
if (timer) {
|
|
144
328
|
clearInterval(timer);
|
|
145
329
|
timer = null;
|
|
146
330
|
}
|
|
147
331
|
try {
|
|
148
|
-
flush(state);
|
|
332
|
+
await flush(state);
|
|
149
333
|
} catch (error) {
|
|
150
334
|
console.error("runtime state snapshot final flush failed", error);
|
|
151
335
|
}
|
|
@@ -153,6 +337,7 @@ function createRuntimeStateStore(config = {}) {
|
|
|
153
337
|
|
|
154
338
|
return {
|
|
155
339
|
enabled,
|
|
340
|
+
storageMode,
|
|
156
341
|
filePath,
|
|
157
342
|
intervalMs,
|
|
158
343
|
inspect,
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const packageJson = require("../package.json");
|
|
4
|
+
|
|
5
|
+
function buildSoftLaunchPack() {
|
|
6
|
+
return {
|
|
7
|
+
ok: true,
|
|
8
|
+
product: packageJson.name,
|
|
9
|
+
category: "machine-commerce-soft-launch-pack",
|
|
10
|
+
message_core: {
|
|
11
|
+
headline: "governed machine commerce for builders who need paid execution, reusable credits, and proof-aware followthrough",
|
|
12
|
+
short_pitch: "xytara gives agent builders and tool authors a machine-commerce spine for quote, pay, execute, inspect, and continue into proof without stitching together separate systems.",
|
|
13
|
+
when_to_lead: [
|
|
14
|
+
"when an agent or tool needs a paid capability path",
|
|
15
|
+
"when repeat usage should use funded account balance instead of repeated manual payment",
|
|
16
|
+
"when execution must stay inspectable and continue cleanly into proof review"
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
first_targets: [
|
|
20
|
+
{
|
|
21
|
+
audience_ref: "agent_builder",
|
|
22
|
+
first_message: "start with one paid machine run and inspect the release center afterward",
|
|
23
|
+
first_proof_path: "scenario.direct_pay.trust_verify"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
audience_ref: "adapter_author",
|
|
27
|
+
first_message: "start from the minimal third-party starter and inspect promotion workflow next",
|
|
28
|
+
first_proof_path: "partner.execution.minimal_echo"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
audience_ref: "tool_or_marketplace_author",
|
|
32
|
+
first_message: "start with the launch summary and compare xytara against patchwork alternatives",
|
|
33
|
+
first_proof_path: "scenario.direct_pay.trust_verify"
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
first_artifacts: {
|
|
37
|
+
release_center: "/v1/release-center/summary",
|
|
38
|
+
announcement: "/v1/announcement-pack/summary",
|
|
39
|
+
outreach_proof: "/v1/outreach-proof/summary",
|
|
40
|
+
adapter_partners: "/v1/adapter-partners/summary",
|
|
41
|
+
first_cli: "xytara-release --center --summary",
|
|
42
|
+
first_run_cli: "xytara-run --url https://xytara.onrender.com --account acct_demo --command \"cli-run\" --task trust.verify --body-json '{\"subject_id\":\"subject-1\"}' --wallet-id merchant_wallet_main --wallet-secret YOUR_LOCAL_SIGNED_SECRET --txid YOUR_BSV_TXID"
|
|
43
|
+
},
|
|
44
|
+
outreach_sequence: [
|
|
45
|
+
"send the short pitch and first proof path to a small builder set",
|
|
46
|
+
"point each audience to the matching first artifact and cli",
|
|
47
|
+
"watch which first path they actually try",
|
|
48
|
+
"collect install, wording, and trust-posture confusion",
|
|
49
|
+
"tighten docs and first-run friction before broader outreach"
|
|
50
|
+
],
|
|
51
|
+
feedback_watchlist: [
|
|
52
|
+
"install friction",
|
|
53
|
+
"first-run confusion",
|
|
54
|
+
"adapter authoring confusion",
|
|
55
|
+
"promotion trust-model confusion",
|
|
56
|
+
"difference between direct pay and funded-runtime paths"
|
|
57
|
+
]
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function summarizeSoftLaunchPack() {
|
|
62
|
+
const pack = buildSoftLaunchPack();
|
|
63
|
+
return {
|
|
64
|
+
ok: true,
|
|
65
|
+
product: pack.product,
|
|
66
|
+
category: pack.category,
|
|
67
|
+
target_count: pack.first_targets.length,
|
|
68
|
+
artifact_count: Object.keys(pack.first_artifacts).length,
|
|
69
|
+
outreach_step_count: pack.outreach_sequence.length,
|
|
70
|
+
feedback_watch_count: pack.feedback_watchlist.length,
|
|
71
|
+
first_cli: pack.first_artifacts.first_cli
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
module.exports = {
|
|
76
|
+
buildSoftLaunchPack,
|
|
77
|
+
summarizeSoftLaunchPack
|
|
78
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xytara",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Machine commerce SDK for discovery, quoting, execution, lifecycle inspection, and adapters.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -47,6 +47,18 @@
|
|
|
47
47
|
"PUBLISH_PLAN.md",
|
|
48
48
|
".env.example",
|
|
49
49
|
"README.md",
|
|
50
|
+
"PROGRAM_STATUS.md",
|
|
51
|
+
"OPERATOR_START_HERE.md",
|
|
52
|
+
"OPERATIONS_RUNBOOK.md",
|
|
53
|
+
"PROGRAM_COMPLETE_RELEASE.md",
|
|
54
|
+
"WHY_XYTARA_XOONYA.md",
|
|
55
|
+
"CARRIED_HANDOFF_DEMO.md",
|
|
56
|
+
"PARTNER_READY_PATH.md",
|
|
57
|
+
"EXAMPLE_PATHS.md",
|
|
58
|
+
"PUBLIC_DEMO_SCRIPT.md",
|
|
59
|
+
"SUPABASE_RUNTIME_STATE_SETUP.md",
|
|
60
|
+
"ADAPTER_START_HERE.md",
|
|
61
|
+
"examples/",
|
|
50
62
|
"BSV_TERANODE_SETUP.md",
|
|
51
63
|
"REAL_PAYMENT_SETUP.md",
|
|
52
64
|
"START_HERE.md",
|