@ouro.bot/cli 0.1.0-alpha.703 → 0.1.0-alpha.704
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/changelog.json
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
|
|
3
3
|
"versions": [
|
|
4
|
+
{
|
|
5
|
+
"version": "0.1.0-alpha.704",
|
|
6
|
+
"changes": [
|
|
7
|
+
"Restore RSVP notification copy and harden RSVP run ledgers.",
|
|
8
|
+
"Preserve loose RSVP spend-ledger history while adding cold-start state coverage."
|
|
9
|
+
]
|
|
10
|
+
},
|
|
4
11
|
{
|
|
5
12
|
"version": "0.1.0-alpha.703",
|
|
6
13
|
"changes": [
|
|
@@ -4,7 +4,7 @@ exports.guestDisplayName = guestDisplayName;
|
|
|
4
4
|
exports.computeRsvpDelta = computeRsvpDelta;
|
|
5
5
|
exports.renderRsvpReport = renderRsvpReport;
|
|
6
6
|
const runtime_1 = require("../nerves/runtime");
|
|
7
|
-
const RSVP_REPORT_FOOTER = "🤖 Beep boop!
|
|
7
|
+
const RSVP_REPORT_FOOTER = "🤖 Beep boop! I'm a script, not Slugger — no need to reply here!";
|
|
8
8
|
function byId(left, right) {
|
|
9
9
|
return left.id.localeCompare(right.id);
|
|
10
10
|
}
|
package/dist/rsvp/habit-stage.js
CHANGED
|
@@ -38,6 +38,8 @@ const fs = __importStar(require("node:fs"));
|
|
|
38
38
|
const path = __importStar(require("node:path"));
|
|
39
39
|
const habit_parser_1 = require("../heart/habits/habit-parser");
|
|
40
40
|
const runtime_1 = require("../nerves/runtime");
|
|
41
|
+
const outbound_state_1 = require("./outbound-state");
|
|
42
|
+
const spend_ledger_1 = require("./spend-ledger");
|
|
41
43
|
const habit_policy_1 = require("./habit-policy");
|
|
42
44
|
function defaultRsvpHabitMetadata(mode) {
|
|
43
45
|
return {
|
|
@@ -62,17 +64,20 @@ function stagedHabitBody() {
|
|
|
62
64
|
function stageRsvpHabit(input) {
|
|
63
65
|
const habitPath = path.join(input.agentRoot, "habits", `${habit_policy_1.RSVP_HABIT_NAME}.md`);
|
|
64
66
|
const rsvp = defaultRsvpHabitMetadata(input.mode);
|
|
67
|
+
const created = (input.now ?? new Date()).toISOString();
|
|
65
68
|
const content = (0, habit_parser_1.renderHabitFile)({
|
|
66
69
|
title: "RSVP Ari & Rachel",
|
|
67
70
|
status: "active",
|
|
68
71
|
cadence: input.cadence,
|
|
69
|
-
created
|
|
72
|
+
created,
|
|
70
73
|
tools: [...habit_policy_1.RSVP_HABIT_ALLOWED_TOOLS],
|
|
71
74
|
continuity: { mode: "stateful" },
|
|
72
75
|
rsvp,
|
|
73
76
|
}, stagedHabitBody());
|
|
74
77
|
fs.mkdirSync(path.dirname(habitPath), { recursive: true });
|
|
75
78
|
fs.writeFileSync(habitPath, content, "utf-8");
|
|
79
|
+
(0, outbound_state_1.ensureRsvpOutboundState)(input.agentRoot, created);
|
|
80
|
+
(0, spend_ledger_1.ensureRsvpSpendLedger)(input.agentRoot, created);
|
|
76
81
|
(0, runtime_1.emitNervesEvent)({
|
|
77
82
|
component: "rsvp",
|
|
78
83
|
event: "rsvp.habit_staged",
|
|
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.RSVP_OUTBOUND_STATE_POLICY_VERSION = void 0;
|
|
37
37
|
exports.readRsvpOutboundState = readRsvpOutboundState;
|
|
38
|
+
exports.ensureRsvpOutboundState = ensureRsvpOutboundState;
|
|
38
39
|
exports.writeRsvpBaseline = writeRsvpBaseline;
|
|
39
40
|
exports.decideRsvpOutboundReport = decideRsvpOutboundReport;
|
|
40
41
|
exports.recordRsvpOutboundAttempt = recordRsvpOutboundAttempt;
|
|
@@ -135,6 +136,19 @@ function writeState(agentRoot, state) {
|
|
|
135
136
|
fs.renameSync(tmp, filePath);
|
|
136
137
|
return state;
|
|
137
138
|
}
|
|
139
|
+
function ensureRsvpOutboundState(agentRoot, now = new Date().toISOString()) {
|
|
140
|
+
const filePath = rsvpOutboundStatePath(agentRoot);
|
|
141
|
+
if (fs.existsSync(filePath))
|
|
142
|
+
return readRsvpOutboundState(agentRoot);
|
|
143
|
+
const state = writeState(agentRoot, emptyState(now));
|
|
144
|
+
(0, runtime_1.emitNervesEvent)({
|
|
145
|
+
component: "rsvp",
|
|
146
|
+
event: "rsvp.outbound_state_initialized",
|
|
147
|
+
message: "initialized RSVP outbound state",
|
|
148
|
+
meta: { updatedAt: state.updatedAt },
|
|
149
|
+
});
|
|
150
|
+
return state;
|
|
151
|
+
}
|
|
138
152
|
function writeRsvpBaseline(input) {
|
|
139
153
|
const current = readRsvpOutboundState(input.agentRoot);
|
|
140
154
|
const state = writeState(input.agentRoot, {
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.RSVP_SPEND_LEDGER_POLICY_VERSION = void 0;
|
|
37
|
+
exports.readRsvpSpendLedger = readRsvpSpendLedger;
|
|
38
|
+
exports.ensureRsvpSpendLedger = ensureRsvpSpendLedger;
|
|
39
|
+
exports.recordRsvpSpendLedgerRun = recordRsvpSpendLedgerRun;
|
|
40
|
+
const fs = __importStar(require("node:fs"));
|
|
41
|
+
const path = __importStar(require("node:path"));
|
|
42
|
+
const runtime_1 = require("../nerves/runtime");
|
|
43
|
+
exports.RSVP_SPEND_LEDGER_POLICY_VERSION = "rsvp-spend-ledger/v1";
|
|
44
|
+
function ledgerPath(agentRoot) {
|
|
45
|
+
return path.join(agentRoot, "state", "rsvp", "spend-ledger.json");
|
|
46
|
+
}
|
|
47
|
+
function emptyLedger(now) {
|
|
48
|
+
return {
|
|
49
|
+
schemaVersion: 1,
|
|
50
|
+
policyVersion: exports.RSVP_SPEND_LEDGER_POLICY_VERSION,
|
|
51
|
+
createdAt: now,
|
|
52
|
+
updatedAt: now,
|
|
53
|
+
runs: [],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function isRecord(value) {
|
|
57
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
58
|
+
}
|
|
59
|
+
function stringField(record, key) {
|
|
60
|
+
const value = record[key];
|
|
61
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
62
|
+
}
|
|
63
|
+
function isRun(value) {
|
|
64
|
+
const row = value;
|
|
65
|
+
return !!row
|
|
66
|
+
&& row.schemaVersion === 1
|
|
67
|
+
&& typeof row.runId === "string"
|
|
68
|
+
&& typeof row.rootRunId === "string"
|
|
69
|
+
&& typeof row.idempotencyKey === "string"
|
|
70
|
+
&& typeof row.targetHash === "string"
|
|
71
|
+
&& typeof row.habitName === "string"
|
|
72
|
+
&& typeof row.trigger === "string"
|
|
73
|
+
&& typeof row.lifecycle === "string"
|
|
74
|
+
&& typeof row.startedAt === "string"
|
|
75
|
+
&& typeof row.recordedAt === "string"
|
|
76
|
+
&& row.contentStored === false;
|
|
77
|
+
}
|
|
78
|
+
function storedRun(value) {
|
|
79
|
+
if (isRun(value))
|
|
80
|
+
return value;
|
|
81
|
+
return isRecord(value) ? value : null;
|
|
82
|
+
}
|
|
83
|
+
function isLedger(value) {
|
|
84
|
+
const row = value;
|
|
85
|
+
return !!row
|
|
86
|
+
&& row.schemaVersion === 1
|
|
87
|
+
&& row.policyVersion === exports.RSVP_SPEND_LEDGER_POLICY_VERSION
|
|
88
|
+
&& typeof row.createdAt === "string"
|
|
89
|
+
&& typeof row.updatedAt === "string"
|
|
90
|
+
&& Array.isArray(row.runs);
|
|
91
|
+
}
|
|
92
|
+
function readRsvpSpendLedger(agentRoot) {
|
|
93
|
+
const filePath = ledgerPath(agentRoot);
|
|
94
|
+
if (!fs.existsSync(filePath))
|
|
95
|
+
return emptyLedger(new Date().toISOString());
|
|
96
|
+
try {
|
|
97
|
+
const now = new Date().toISOString();
|
|
98
|
+
const parsed = JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
99
|
+
if (!isLedger(parsed)) {
|
|
100
|
+
if (!isRecord(parsed) || !Array.isArray(parsed.runs))
|
|
101
|
+
return emptyLedger(now);
|
|
102
|
+
return {
|
|
103
|
+
schemaVersion: 1,
|
|
104
|
+
policyVersion: exports.RSVP_SPEND_LEDGER_POLICY_VERSION,
|
|
105
|
+
createdAt: stringField(parsed, "createdAt") ?? now,
|
|
106
|
+
updatedAt: stringField(parsed, "updatedAt") ?? now,
|
|
107
|
+
runs: parsed.runs.map(storedRun).filter((run) => run !== null),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
schemaVersion: 1,
|
|
112
|
+
policyVersion: exports.RSVP_SPEND_LEDGER_POLICY_VERSION,
|
|
113
|
+
createdAt: parsed.createdAt,
|
|
114
|
+
updatedAt: parsed.updatedAt,
|
|
115
|
+
runs: parsed.runs.map(storedRun).filter((run) => run !== null),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return emptyLedger(new Date().toISOString());
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function writeLedger(agentRoot, ledger) {
|
|
123
|
+
const filePath = ledgerPath(agentRoot);
|
|
124
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
125
|
+
const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
|
|
126
|
+
fs.writeFileSync(tmp, `${JSON.stringify(ledger, null, 2)}\n`, "utf-8");
|
|
127
|
+
fs.renameSync(tmp, filePath);
|
|
128
|
+
return ledger;
|
|
129
|
+
}
|
|
130
|
+
function ensureRsvpSpendLedger(agentRoot, now = new Date().toISOString()) {
|
|
131
|
+
const filePath = ledgerPath(agentRoot);
|
|
132
|
+
if (fs.existsSync(filePath))
|
|
133
|
+
return readRsvpSpendLedger(agentRoot);
|
|
134
|
+
const ledger = writeLedger(agentRoot, emptyLedger(now));
|
|
135
|
+
(0, runtime_1.emitNervesEvent)({
|
|
136
|
+
component: "rsvp",
|
|
137
|
+
event: "rsvp.spend_ledger_initialized",
|
|
138
|
+
message: "initialized RSVP spend ledger",
|
|
139
|
+
meta: { updatedAt: ledger.updatedAt },
|
|
140
|
+
});
|
|
141
|
+
return ledger;
|
|
142
|
+
}
|
|
143
|
+
function recordRsvpSpendLedgerRun(agentRoot, record) {
|
|
144
|
+
const current = readRsvpSpendLedger(agentRoot);
|
|
145
|
+
const run = {
|
|
146
|
+
schemaVersion: 1,
|
|
147
|
+
runId: record.runId,
|
|
148
|
+
rootRunId: record.rootRunId,
|
|
149
|
+
idempotencyKey: record.idempotencyKey,
|
|
150
|
+
targetHash: record.targetHash,
|
|
151
|
+
habitName: record.senseOrHabit,
|
|
152
|
+
trigger: record.triggerType,
|
|
153
|
+
lifecycle: record.lifecycle,
|
|
154
|
+
startedAt: record.startedAt,
|
|
155
|
+
recordedAt: record.recordedAt,
|
|
156
|
+
...(record.endedAt ? { endedAt: record.endedAt } : {}),
|
|
157
|
+
...(record.usage ? { usage: record.usage } : {}),
|
|
158
|
+
contentStored: false,
|
|
159
|
+
};
|
|
160
|
+
const withoutDuplicate = current.runs.filter((entry) => !(entry.runId === run.runId && entry.lifecycle === run.lifecycle));
|
|
161
|
+
const updated = writeLedger(agentRoot, {
|
|
162
|
+
schemaVersion: 1,
|
|
163
|
+
policyVersion: exports.RSVP_SPEND_LEDGER_POLICY_VERSION,
|
|
164
|
+
createdAt: current.createdAt,
|
|
165
|
+
updatedAt: run.recordedAt,
|
|
166
|
+
runs: [...withoutDuplicate, run],
|
|
167
|
+
});
|
|
168
|
+
(0, runtime_1.emitNervesEvent)({
|
|
169
|
+
component: "rsvp",
|
|
170
|
+
event: "rsvp.spend_ledger_recorded",
|
|
171
|
+
message: "recorded RSVP spend ledger row",
|
|
172
|
+
meta: { runId: run.runId, lifecycle: run.lifecycle, habitName: run.habitName },
|
|
173
|
+
});
|
|
174
|
+
return updated;
|
|
175
|
+
}
|
|
@@ -52,6 +52,7 @@ const tools_base_1 = require("../repertoire/tools-base");
|
|
|
52
52
|
const tools_surface_1 = require("../repertoire/tools-surface");
|
|
53
53
|
const tools_1 = require("../repertoire/tools");
|
|
54
54
|
const habit_policy_1 = require("../rsvp/habit-policy");
|
|
55
|
+
const spend_ledger_1 = require("../rsvp/spend-ledger");
|
|
55
56
|
const run_ledger_1 = require("../heart/run-ledger");
|
|
56
57
|
const autonomy_budget_1 = require("../heart/autonomy-budget");
|
|
57
58
|
function isUsageData(value) {
|
|
@@ -108,14 +109,29 @@ function habitRunLedgerBase(habitRun) {
|
|
|
108
109
|
}
|
|
109
110
|
function recordHabitRunLedger(habitRun, lifecycle, endedAt) {
|
|
110
111
|
const usage = extractUsageFromHabitResults(habitRun.results);
|
|
111
|
-
|
|
112
|
+
const record = (0, run_ledger_1.createRunLedgerRecord)({
|
|
112
113
|
...habitRunLedgerBase(habitRun),
|
|
113
114
|
lifecycle,
|
|
114
115
|
...(endedAt ? { endedAt } : {}),
|
|
115
116
|
...(lifecycle === "completed" || lifecycle === "error"
|
|
116
117
|
? { usage: (0, run_ledger_1.usageMetadataFromUsageData)(usage, usage ? "provider" : "none") }
|
|
117
118
|
: {}),
|
|
118
|
-
})
|
|
119
|
+
});
|
|
120
|
+
(0, run_ledger_1.appendRunLedgerRecordNonFatal)(habitRun.agentRoot, record);
|
|
121
|
+
if (habitRun.rsvpPolicy) {
|
|
122
|
+
try {
|
|
123
|
+
(0, spend_ledger_1.recordRsvpSpendLedgerRun)(habitRun.agentRoot, record);
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
(0, runtime_1.emitNervesEvent)({
|
|
127
|
+
level: "error",
|
|
128
|
+
component: "rsvp",
|
|
129
|
+
event: "rsvp.spend_ledger_record_error",
|
|
130
|
+
message: "failed to record RSVP spend ledger row",
|
|
131
|
+
meta: { runId: record.runId, lifecycle, error: String(error) },
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
119
135
|
}
|
|
120
136
|
function reserveHabitAutonomyBudget(habitRun, nowIso) {
|
|
121
137
|
const target = {
|