@synaplink/orqlaude 0.8.0 → 0.9.3
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/dist/__tests__/v09.test.d.ts +1 -0
- package/dist/__tests__/v09.test.js +189 -0
- package/dist/__tests__/v09.test.js.map +1 -0
- package/dist/__tests__/v092.test.d.ts +1 -0
- package/dist/__tests__/v092.test.js +125 -0
- package/dist/__tests__/v092.test.js.map +1 -0
- package/dist/cli/easter_egg.js +127 -39
- package/dist/cli/easter_egg.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/lib/jsonl_tail.d.ts +68 -5
- package/dist/lib/jsonl_tail.js +70 -11
- package/dist/lib/jsonl_tail.js.map +1 -1
- package/dist/lib/spawn_cli.d.ts +26 -0
- package/dist/lib/spawn_cli.js +45 -1
- package/dist/lib/spawn_cli.js.map +1 -1
- package/dist/lib/state.d.ts +33 -0
- package/dist/lib/state.js +14 -4
- package/dist/lib/state.js.map +1 -1
- package/dist/lib/telegram_status.js +7 -1
- package/dist/lib/telegram_status.js.map +1 -1
- package/dist/lib/version.d.ts +18 -0
- package/dist/lib/version.js +19 -0
- package/dist/lib/version.js.map +1 -0
- package/dist/server.js +2 -1
- package/dist/server.js.map +1 -1
- package/dist/telegram/notifier.js +33 -1
- package/dist/telegram/notifier.js.map +1 -1
- package/dist/tools/dispatch.d.ts +29 -1
- package/dist/tools/dispatch.js +445 -35
- package/dist/tools/dispatch.js.map +1 -1
- package/dist/tools/lifecycle.js +44 -2
- package/dist/tools/lifecycle.js.map +1 -1
- package/dist/tools/ping.js +2 -1
- package/dist/tools/ping.js.map +1 -1
- package/dist/tools/planning.js +4 -1
- package/dist/tools/planning.js.map +1 -1
- package/dist/tools/userio.js +16 -6
- package/dist/tools/userio.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { test } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { promises as fs } from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import os from "node:os";
|
|
6
|
+
import { snapshotSession, clearTailCache } from "../lib/jsonl_tail.js";
|
|
7
|
+
import { readChildExitRecord } from "../lib/spawn_cli.js";
|
|
8
|
+
/**
|
|
9
|
+
* v0.9.0 — observability overhaul.
|
|
10
|
+
*
|
|
11
|
+
* Covers:
|
|
12
|
+
* • A. snapshotSession falls back to stdoutPath when JSONL is missing
|
|
13
|
+
* • E. readChildExitRecord parses the exit JSON file
|
|
14
|
+
* • D. orphan notifications round-trip via state.ts schema
|
|
15
|
+
* • F. wait_for_status_change fingerprint changes on key transitions
|
|
16
|
+
* (smoke; the long-poll loop itself is integration-tested by
|
|
17
|
+
* running a fleet end-to-end).
|
|
18
|
+
* • cleanup_worktrees lock-release predicate (state mutation only).
|
|
19
|
+
*
|
|
20
|
+
* Smoke style: build temp files / state, call the unit-under-test
|
|
21
|
+
* directly, assert observable behavior. No subprocess spawning - those
|
|
22
|
+
* paths are covered by manual integration runs.
|
|
23
|
+
*/
|
|
24
|
+
async function mkTempDir(prefix) {
|
|
25
|
+
const raw = await fs.mkdtemp(path.join(os.tmpdir(), prefix));
|
|
26
|
+
return await fs.realpath(raw);
|
|
27
|
+
}
|
|
28
|
+
// ---- A: stdoutPath fallback in snapshotSession -----------------------------
|
|
29
|
+
test("v0.9.0 A: snapshotSession reads tokens from stdout log when JSONL is missing", async () => {
|
|
30
|
+
clearTailCache();
|
|
31
|
+
const dir = await mkTempDir("orq-v09-A-");
|
|
32
|
+
const stdoutPath = path.join(dir, ".orqlaude.stdout.log");
|
|
33
|
+
// Write two stream-json events: one assistant with usage, one result.
|
|
34
|
+
const events = [
|
|
35
|
+
{
|
|
36
|
+
type: "assistant",
|
|
37
|
+
message: {
|
|
38
|
+
content: [{ type: "text", text: "Working on it" }],
|
|
39
|
+
usage: { input_tokens: 100, output_tokens: 50, cache_read_input_tokens: 0, cache_creation_input_tokens: 0 },
|
|
40
|
+
},
|
|
41
|
+
timestamp: new Date().toISOString(),
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
type: "result",
|
|
45
|
+
subtype: "completed",
|
|
46
|
+
total_cost_usd: 0.0012,
|
|
47
|
+
timestamp: new Date().toISOString(),
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
await fs.writeFile(stdoutPath, events.map((e) => JSON.stringify(e)).join("\n") + "\n");
|
|
51
|
+
// session id is fake - the canonical JSONL path won't exist.
|
|
52
|
+
const fakeSession = "00000000-0000-4000-8000-000000000000";
|
|
53
|
+
const snap = await snapshotSession("/tmp/non-existent-cwd", fakeSession, stdoutPath);
|
|
54
|
+
assert.equal(snap.exists, true);
|
|
55
|
+
assert.equal(snap.source, "stdout_log");
|
|
56
|
+
assert.equal(snap.resolvedPath, stdoutPath);
|
|
57
|
+
assert.equal(snap.inputTokens, 100);
|
|
58
|
+
assert.equal(snap.outputTokens, 50);
|
|
59
|
+
assert.equal(snap.terminated, true);
|
|
60
|
+
assert.equal(snap.terminationReason, "completed");
|
|
61
|
+
});
|
|
62
|
+
test("v0.9.0 A: snapshotSession returns 'none' source when neither file exists", async () => {
|
|
63
|
+
clearTailCache();
|
|
64
|
+
const fakeSession = "11111111-0000-4000-8000-000000000000";
|
|
65
|
+
const snap = await snapshotSession("/tmp/non-existent-cwd-2", fakeSession);
|
|
66
|
+
assert.equal(snap.exists, false);
|
|
67
|
+
assert.equal(snap.source, "none");
|
|
68
|
+
assert.equal(snap.resolvedPath, null);
|
|
69
|
+
});
|
|
70
|
+
test("v0.9.0 A: snapshotSession prefers JSONL when both exist", async () => {
|
|
71
|
+
clearTailCache();
|
|
72
|
+
const dir = await mkTempDir("orq-v09-A-pref-");
|
|
73
|
+
const stdoutPath = path.join(dir, ".orqlaude.stdout.log");
|
|
74
|
+
// Stdout says 50 input tokens; JSONL we'll forge to say 200.
|
|
75
|
+
await fs.writeFile(stdoutPath, JSON.stringify({
|
|
76
|
+
type: "assistant",
|
|
77
|
+
message: { content: [], usage: { input_tokens: 50, output_tokens: 0 } },
|
|
78
|
+
}) + "\n");
|
|
79
|
+
// Build the JSONL at the canonical path so the resolver picks it.
|
|
80
|
+
const sessionId = "22222222-0000-4000-8000-000000000000";
|
|
81
|
+
// We need to mirror jsonlPathFor's encoding without importing it again.
|
|
82
|
+
const fakeCwd = await mkTempDir("orq-v09-A-cwd-");
|
|
83
|
+
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
84
|
+
const jsonlDir = path.join(home, ".claude", "projects", fakeCwd.replace(/\//g, "-"));
|
|
85
|
+
await fs.mkdir(jsonlDir, { recursive: true });
|
|
86
|
+
const jsonlPath = path.join(jsonlDir, `${sessionId}.jsonl`);
|
|
87
|
+
await fs.writeFile(jsonlPath, JSON.stringify({
|
|
88
|
+
type: "assistant",
|
|
89
|
+
message: { content: [], usage: { input_tokens: 200, output_tokens: 0 } },
|
|
90
|
+
}) + "\n");
|
|
91
|
+
try {
|
|
92
|
+
const snap = await snapshotSession(fakeCwd, sessionId, stdoutPath);
|
|
93
|
+
assert.equal(snap.source, "jsonl");
|
|
94
|
+
assert.equal(snap.resolvedPath, jsonlPath);
|
|
95
|
+
assert.equal(snap.inputTokens, 200, "JSONL wins over stdout log when both exist");
|
|
96
|
+
}
|
|
97
|
+
finally {
|
|
98
|
+
await fs.rm(jsonlPath, { force: true });
|
|
99
|
+
await fs.rm(jsonlDir, { recursive: true, force: true });
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
// ---- E: readChildExitRecord ------------------------------------------------
|
|
103
|
+
test("v0.9.0 E: readChildExitRecord returns null when file missing", async () => {
|
|
104
|
+
const dir = await mkTempDir("orq-v09-E-");
|
|
105
|
+
const exitPath = path.join(dir, ".orqlaude.exit.json");
|
|
106
|
+
const rec = await readChildExitRecord(exitPath);
|
|
107
|
+
assert.equal(rec, null);
|
|
108
|
+
});
|
|
109
|
+
test("v0.9.0 E: readChildExitRecord parses a written record", async () => {
|
|
110
|
+
const dir = await mkTempDir("orq-v09-E2-");
|
|
111
|
+
const exitPath = path.join(dir, ".orqlaude.exit.json");
|
|
112
|
+
const written = {
|
|
113
|
+
exit_code: 0,
|
|
114
|
+
signal: null,
|
|
115
|
+
terminated_at: Date.now(),
|
|
116
|
+
success: true,
|
|
117
|
+
};
|
|
118
|
+
await fs.writeFile(exitPath, JSON.stringify(written));
|
|
119
|
+
const rec = await readChildExitRecord(exitPath);
|
|
120
|
+
assert.ok(rec, "should parse");
|
|
121
|
+
assert.equal(rec.exit_code, 0);
|
|
122
|
+
assert.equal(rec.signal, null);
|
|
123
|
+
assert.equal(rec.success, true);
|
|
124
|
+
assert.equal(typeof rec.terminated_at, "number");
|
|
125
|
+
});
|
|
126
|
+
test("v0.9.0 E: readChildExitRecord rejects malformed json gracefully", async () => {
|
|
127
|
+
const dir = await mkTempDir("orq-v09-E3-");
|
|
128
|
+
const exitPath = path.join(dir, ".orqlaude.exit.json");
|
|
129
|
+
await fs.writeFile(exitPath, "{not json");
|
|
130
|
+
const rec = await readChildExitRecord(exitPath);
|
|
131
|
+
assert.equal(rec, null);
|
|
132
|
+
});
|
|
133
|
+
// ---- D: orphan-notification migration --------------------------------------
|
|
134
|
+
test("v0.9.0 D: state.ts migrate fills orphanNotifications on a fresh v3 state", async () => {
|
|
135
|
+
const stateDir = await mkTempDir("orq-v09-D-");
|
|
136
|
+
// Write a hand-rolled state.json that omits the orphan arrays (mimicking
|
|
137
|
+
// a v3 file written by v0.8.0).
|
|
138
|
+
await fs.writeFile(path.join(stateDir, "orqlaude-state.json"), JSON.stringify({ schemaVersion: 3, plans: {} }));
|
|
139
|
+
const { StateStore } = await import("../lib/state.js");
|
|
140
|
+
const store = new StateStore(stateDir);
|
|
141
|
+
const orphans = await store.read((s) => ({
|
|
142
|
+
n: s.orphanNotifications,
|
|
143
|
+
r: s.orphanResponseRequests,
|
|
144
|
+
}));
|
|
145
|
+
// v0.9.1: pin the migration contract. The migrate fn explicitly
|
|
146
|
+
// initializes these arrays (out.orphanNotifications = out.orphanNotifications
|
|
147
|
+
// ?? []) so a load of a v3-without-orphans file must result in arrays,
|
|
148
|
+
// not undefineds. The notifier's `?? []` is defense-in-depth, not the
|
|
149
|
+
// primary contract.
|
|
150
|
+
assert.ok(Array.isArray(orphans.n), "orphanNotifications should be initialized as []");
|
|
151
|
+
assert.ok(Array.isArray(orphans.r), "orphanResponseRequests should be initialized as []");
|
|
152
|
+
assert.equal(orphans.n.length, 0);
|
|
153
|
+
assert.equal(orphans.r.length, 0);
|
|
154
|
+
});
|
|
155
|
+
test("v0.9.0 D: notify_user without plan_id pushes to orphan queue", async () => {
|
|
156
|
+
const stateDir = await mkTempDir("orq-v09-D2-");
|
|
157
|
+
const { StateStore } = await import("../lib/state.js");
|
|
158
|
+
const store = new StateStore(stateDir);
|
|
159
|
+
// Simulate what notify_user does when plan_id is absent.
|
|
160
|
+
await store.update((state) => {
|
|
161
|
+
state.orphanNotifications = state.orphanNotifications ?? [];
|
|
162
|
+
state.orphanNotifications.push({
|
|
163
|
+
id: "abc123",
|
|
164
|
+
text: "test ping",
|
|
165
|
+
urgency: "normal",
|
|
166
|
+
createdAt: Date.now(),
|
|
167
|
+
delivered: false,
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
const out = await store.read((s) => s.orphanNotifications);
|
|
171
|
+
assert.equal(out.length, 1);
|
|
172
|
+
assert.equal(out[0].text, "test ping");
|
|
173
|
+
});
|
|
174
|
+
// ---- F: fingerprint computation --------------------------------------------
|
|
175
|
+
//
|
|
176
|
+
// We can't call wait_for_status_change directly (it's tool-registered) but
|
|
177
|
+
// the fingerprint shape is part of the contract. This test pins the
|
|
178
|
+
// observable contract: token deltas of < 1 KB don't churn the fingerprint,
|
|
179
|
+
// but a status transition does.
|
|
180
|
+
test("v0.9.0 F: fingerprint shape is stable across sub-KB token deltas", () => {
|
|
181
|
+
const fp = (status, tokens) => `${status}|t1:${status}::${Math.floor(tokens / 1024)}::0:?`;
|
|
182
|
+
// 500-token to 800-token delta: same KB bucket.
|
|
183
|
+
assert.equal(fp("running", 500), fp("running", 800));
|
|
184
|
+
// 500 to 1500: different KB bucket.
|
|
185
|
+
assert.notEqual(fp("running", 500), fp("running", 1500));
|
|
186
|
+
// Status transition: always different.
|
|
187
|
+
assert.notEqual(fp("running", 500), fp("done", 500));
|
|
188
|
+
});
|
|
189
|
+
//# sourceMappingURL=v09.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v09.test.js","sourceRoot":"","sources":["../../src/__tests__/v09.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { test } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { promises as fs } from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import os from "node:os";
|
|
6
|
+
import { snapshotSession, clearTailCache } from "../lib/jsonl_tail.js";
|
|
7
|
+
/**
|
|
8
|
+
* v0.9.2 — billed-vs-cached token accounting.
|
|
9
|
+
*
|
|
10
|
+
* Covers:
|
|
11
|
+
* • SessionSnapshot exposes separate billedTokens / cachedTokens / total
|
|
12
|
+
* • billedTokens = input + output (Plan-cost-relevant)
|
|
13
|
+
* • cachedTokens = cache_read + cache_creation (free on the Plan)
|
|
14
|
+
* • totalEffectiveTokens = sum (back-compat)
|
|
15
|
+
* • Plan.budgetMode defaults to "billed" via newPlan
|
|
16
|
+
*
|
|
17
|
+
* The budget-enforcement flow (status() / wait_for_status_change calling
|
|
18
|
+
* enforceBudget with the right bucket) is covered by integration-style
|
|
19
|
+
* runs against a live fleet; the unit tests here pin the snapshot maths.
|
|
20
|
+
*/
|
|
21
|
+
async function mkTempDir(prefix) {
|
|
22
|
+
const raw = await fs.mkdtemp(path.join(os.tmpdir(), prefix));
|
|
23
|
+
return await fs.realpath(raw);
|
|
24
|
+
}
|
|
25
|
+
test("v0.9.2: snapshotSession exposes billed and cached buckets separately", async () => {
|
|
26
|
+
clearTailCache();
|
|
27
|
+
const dir = await mkTempDir("orq-v092-buckets-");
|
|
28
|
+
const stdoutPath = path.join(dir, ".orqlaude.stdout.log");
|
|
29
|
+
// One assistant event with usage covering all four bucket fields.
|
|
30
|
+
await fs.writeFile(stdoutPath, JSON.stringify({
|
|
31
|
+
type: "assistant",
|
|
32
|
+
message: {
|
|
33
|
+
content: [{ type: "text", text: "x" }],
|
|
34
|
+
usage: {
|
|
35
|
+
input_tokens: 100,
|
|
36
|
+
output_tokens: 50,
|
|
37
|
+
cache_read_input_tokens: 8000,
|
|
38
|
+
cache_creation_input_tokens: 200,
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
timestamp: new Date().toISOString(),
|
|
42
|
+
}) + "\n");
|
|
43
|
+
const fakeSession = "00000000-0000-4000-8000-000000000aaa";
|
|
44
|
+
const snap = await snapshotSession("/tmp/non-existent-cwd-v092", fakeSession, stdoutPath);
|
|
45
|
+
assert.equal(snap.billedTokens, 150, "input + output only");
|
|
46
|
+
assert.equal(snap.cachedTokens, 8200, "cache_read + cache_creation");
|
|
47
|
+
assert.equal(snap.totalEffectiveTokens, 8350, "sum of all four buckets");
|
|
48
|
+
assert.equal(snap.totalEffectiveTokens, snap.billedTokens + snap.cachedTokens, "total = billed + cached");
|
|
49
|
+
});
|
|
50
|
+
test("v0.9.2: billed bucket excludes cache reads (the user is on the Claude Plan)", async () => {
|
|
51
|
+
clearTailCache();
|
|
52
|
+
const dir = await mkTempDir("orq-v092-billed-");
|
|
53
|
+
const stdoutPath = path.join(dir, ".orqlaude.stdout.log");
|
|
54
|
+
// A typical agent turn: small fresh input, small output, huge cache read.
|
|
55
|
+
// This mirrors the pattern we saw in the v0.9.1 live test where Agnets
|
|
56
|
+
// were reading 100k+ from cache per turn.
|
|
57
|
+
await fs.writeFile(stdoutPath, [
|
|
58
|
+
JSON.stringify({
|
|
59
|
+
type: "assistant",
|
|
60
|
+
message: {
|
|
61
|
+
content: [],
|
|
62
|
+
usage: { input_tokens: 200, output_tokens: 100, cache_read_input_tokens: 100000 },
|
|
63
|
+
},
|
|
64
|
+
}),
|
|
65
|
+
JSON.stringify({
|
|
66
|
+
type: "assistant",
|
|
67
|
+
message: {
|
|
68
|
+
content: [],
|
|
69
|
+
usage: { input_tokens: 150, output_tokens: 80, cache_read_input_tokens: 100000 },
|
|
70
|
+
},
|
|
71
|
+
}),
|
|
72
|
+
].join("\n") + "\n");
|
|
73
|
+
const fakeSession = "00000000-0000-4000-8000-000000000bbb";
|
|
74
|
+
const snap = await snapshotSession("/tmp/non-existent-cwd-v092-b", fakeSession, stdoutPath);
|
|
75
|
+
assert.equal(snap.billedTokens, 530, "200+100 + 150+80 = 530 - what the Plan cares about");
|
|
76
|
+
assert.equal(snap.cachedTokens, 200000, "two turns of 100k cache reads");
|
|
77
|
+
assert.equal(snap.totalEffectiveTokens, 200530);
|
|
78
|
+
// The KEY ratio: cache reads are 376x larger than billed. A budget cap
|
|
79
|
+
// applied to `totalEffectiveTokens` would fire spuriously; applied to
|
|
80
|
+
// `billedTokens` it reflects real Plan usage.
|
|
81
|
+
const inflationRatio = snap.totalEffectiveTokens / snap.billedTokens;
|
|
82
|
+
assert.ok(inflationRatio > 100, `cache inflates the total by ${Math.round(inflationRatio)}x`);
|
|
83
|
+
});
|
|
84
|
+
test("v0.9.2: empty snapshot has zeros for all three rollups", async () => {
|
|
85
|
+
clearTailCache();
|
|
86
|
+
const snap = await snapshotSession("/tmp/non-existent-cwd-v092-empty", "11111111-0000-4000-8000-000000000000");
|
|
87
|
+
assert.equal(snap.billedTokens, 0);
|
|
88
|
+
assert.equal(snap.cachedTokens, 0);
|
|
89
|
+
assert.equal(snap.totalEffectiveTokens, 0);
|
|
90
|
+
});
|
|
91
|
+
test("v0.9.2: Plan.budgetMode defaults to undefined on newPlan; consumers treat undefined as 'billed'", async () => {
|
|
92
|
+
const { newPlan } = await import("../lib/state.js");
|
|
93
|
+
const p = newPlan("test", 100000, [
|
|
94
|
+
{ title: "a", prompt: "p", tldr: "t" },
|
|
95
|
+
{ title: "b", prompt: "p", tldr: "t" },
|
|
96
|
+
]);
|
|
97
|
+
// newPlan itself doesn't set budgetMode - create_plan does. Both
|
|
98
|
+
// semantics are valid; consumers must fallback to "billed" on undefined.
|
|
99
|
+
// This pins the contract.
|
|
100
|
+
assert.ok(p.budgetMode === undefined || p.budgetMode === "billed");
|
|
101
|
+
});
|
|
102
|
+
test("v0.9.2: total = billed + cached invariant holds across mixed events", async () => {
|
|
103
|
+
clearTailCache();
|
|
104
|
+
const dir = await mkTempDir("orq-v092-invariant-");
|
|
105
|
+
const stdoutPath = path.join(dir, ".orqlaude.stdout.log");
|
|
106
|
+
// Mix of event shapes: assistant with full usage, assistant with partial,
|
|
107
|
+
// user (no usage), result row.
|
|
108
|
+
await fs.writeFile(stdoutPath, [
|
|
109
|
+
JSON.stringify({
|
|
110
|
+
type: "assistant",
|
|
111
|
+
message: { content: [], usage: { input_tokens: 10, output_tokens: 5, cache_read_input_tokens: 100, cache_creation_input_tokens: 20 } },
|
|
112
|
+
}),
|
|
113
|
+
JSON.stringify({ type: "user", message: { content: "noop" } }),
|
|
114
|
+
JSON.stringify({
|
|
115
|
+
type: "assistant",
|
|
116
|
+
message: { content: [], usage: { input_tokens: 7, output_tokens: 3 } },
|
|
117
|
+
}),
|
|
118
|
+
JSON.stringify({ type: "result", subtype: "completed" }),
|
|
119
|
+
].join("\n") + "\n");
|
|
120
|
+
const snap = await snapshotSession("/tmp/non-existent-cwd-v092-inv", "22222222-0000-4000-8000-000000000000", stdoutPath);
|
|
121
|
+
assert.equal(snap.billedTokens, 25); // 10+5 + 7+3
|
|
122
|
+
assert.equal(snap.cachedTokens, 120); // 100 + 20
|
|
123
|
+
assert.equal(snap.totalEffectiveTokens, snap.billedTokens + snap.cachedTokens);
|
|
124
|
+
});
|
|
125
|
+
//# sourceMappingURL=v092.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v092.test.js","sourceRoot":"","sources":["../../src/__tests__/v092.test.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/easter_egg.js
CHANGED
|
@@ -1,18 +1,40 @@
|
|
|
1
1
|
import { TAGLINES } from "./taglines.js";
|
|
2
2
|
import { style } from "../lib/style.js";
|
|
3
3
|
/**
|
|
4
|
-
* Bare `orql` easter egg —
|
|
5
|
-
*
|
|
4
|
+
* Bare `orql` easter egg — typewriter cycling through 149 tagline variants
|
|
5
|
+
* beneath the orqlaude diamond. Runs until Ctrl-C / Ctrl-D.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* v0.9.3 rewrite. Two fixes over the v0.6.1 implementation:
|
|
8
|
+
*
|
|
9
|
+
* 1. **Stdin echo no longer bleeds into the line.** Previously the
|
|
10
|
+
* terminal was in cooked mode with echo on, so anything the user
|
|
11
|
+
* typed at the keyboard while the animation ran was printed inline
|
|
12
|
+
* with the tagline — and the `\b \b` erase pass walked back over
|
|
13
|
+
* their characters too, leaving partial garbage when the next
|
|
14
|
+
* tagline started. Now we put stdin in raw mode and silently
|
|
15
|
+
* swallow every byte except Ctrl-C (0x03) and Ctrl-D (0x04).
|
|
16
|
+
*
|
|
17
|
+
* 2. **Full-screen ownership + resize-aware redraw.** Enters the
|
|
18
|
+
* alternate screen buffer (\x1b[?1049h, the same mode vim / less /
|
|
19
|
+
* htop use) so the orqlaude logo claims the entire viewport while
|
|
20
|
+
* running, with nothing else visible. On exit, the original shell
|
|
21
|
+
* contents are restored. We repaint the full frame from top-left on
|
|
22
|
+
* every animation tick AND on `process.stdout` resize events — so
|
|
23
|
+
* the watermark always lives in the top-left corner regardless of
|
|
24
|
+
* window size.
|
|
25
|
+
*
|
|
26
|
+
* If stdout isn't a TTY (piped, CI, redirected), we fall back to a
|
|
27
|
+
* single-line static print and exit immediately. Animation only happens
|
|
28
|
+
* when there's an interactive terminal on the other end.
|
|
9
29
|
*/
|
|
10
30
|
const ESC = "\x1b[";
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
31
|
+
const ALT_SCREEN_ENTER = `${ESC}?1049h`;
|
|
32
|
+
const ALT_SCREEN_LEAVE = `${ESC}?1049l`;
|
|
33
|
+
const HIDE_CURSOR = `${ESC}?25l`;
|
|
34
|
+
const SHOW_CURSOR = `${ESC}?25h`;
|
|
35
|
+
const CLEAR_SCREEN = `${ESC}2J`;
|
|
36
|
+
const MOVE_TO_HOME = `${ESC}H`;
|
|
37
|
+
const moveTo = (row, col) => `${ESC}${row};${col}H`;
|
|
16
38
|
const TYPE_MIN_MS = 28;
|
|
17
39
|
const TYPE_MAX_MS = 90;
|
|
18
40
|
const HOLD_MIN_MS = 1100;
|
|
@@ -21,65 +43,131 @@ const ERASE_MIN_MS = 12;
|
|
|
21
43
|
const ERASE_MAX_MS = 30;
|
|
22
44
|
const BETWEEN_MIN_MS = 280;
|
|
23
45
|
const BETWEEN_MAX_MS = 600;
|
|
46
|
+
// Layout: 1-based rows/cols (ANSI convention).
|
|
47
|
+
// Row 1: blank padding so the logo doesn't kiss the top edge.
|
|
48
|
+
// Row 2-4: logo + wordmark + tagline.
|
|
49
|
+
// The tagline starts at column 14 (after ` ◆◆◆ ` which is exactly
|
|
50
|
+
// 13 visible chars when the ANSI color codes are stripped: 3 spaces + 3
|
|
51
|
+
// glyphs + 6 spaces + 1 = column 14 for the first tagline char).
|
|
52
|
+
const LOGO_ROW = 2;
|
|
53
|
+
const WORDMARK_ROW = 3;
|
|
54
|
+
const TAGLINE_ROW = 4;
|
|
55
|
+
const TAGLINE_COL = 14;
|
|
24
56
|
export async function runEasterEgg() {
|
|
57
|
+
// Non-TTY fallback (piped, redirected, CI). No animation, no alt screen.
|
|
58
|
+
if (!process.stdout.isTTY) {
|
|
59
|
+
process.stdout.write(`◆ orqlaude — ${TAGLINES[0]}\n`);
|
|
60
|
+
return 0;
|
|
61
|
+
}
|
|
25
62
|
return new Promise((resolve) => {
|
|
26
63
|
let stopped = false;
|
|
27
|
-
|
|
64
|
+
let currentText = "";
|
|
65
|
+
const cleanup = () => {
|
|
66
|
+
try {
|
|
67
|
+
if (process.stdin.isTTY && process.stdin.setRawMode) {
|
|
68
|
+
process.stdin.setRawMode(false);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
/* harmless on shutdown */
|
|
73
|
+
}
|
|
74
|
+
process.stdin.removeListener("data", onData);
|
|
75
|
+
process.stdin.pause();
|
|
76
|
+
process.stdout.off("resize", onResize);
|
|
77
|
+
process.removeListener("SIGINT", stop);
|
|
78
|
+
process.stdout.write(SHOW_CURSOR + ALT_SCREEN_LEAVE);
|
|
79
|
+
};
|
|
80
|
+
const stop = () => {
|
|
81
|
+
if (stopped)
|
|
82
|
+
return;
|
|
28
83
|
stopped = true;
|
|
29
|
-
|
|
30
|
-
process.stdout.write(RESET + "\n\n");
|
|
84
|
+
cleanup();
|
|
31
85
|
resolve(0);
|
|
32
86
|
};
|
|
33
|
-
|
|
34
|
-
//
|
|
35
|
-
//
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
//
|
|
87
|
+
// Raw-mode keystroke capture. Every byte is swallowed; Ctrl-C / Ctrl-D
|
|
88
|
+
// exit. This is what stops the user's keyboard from echoing into the
|
|
89
|
+
// animation.
|
|
90
|
+
const onData = (chunk) => {
|
|
91
|
+
for (const byte of chunk) {
|
|
92
|
+
if (byte === 0x03 /* Ctrl-C */ || byte === 0x04 /* Ctrl-D */) {
|
|
93
|
+
stop();
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
// All other input is silently discarded.
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
// Repaint the full frame from the top-left. Called on every animation
|
|
100
|
+
// tick and on terminal resize. Idempotent.
|
|
101
|
+
const paintFrame = () => {
|
|
102
|
+
const out = [
|
|
103
|
+
MOVE_TO_HOME,
|
|
104
|
+
CLEAR_SCREEN,
|
|
105
|
+
moveTo(LOGO_ROW, 4),
|
|
106
|
+
style.coral("◆◆◆"),
|
|
107
|
+
moveTo(WORDMARK_ROW, 3),
|
|
108
|
+
style.coral("◆ ◆"),
|
|
109
|
+
" ",
|
|
110
|
+
style.bold(style.coral("orqlaude")),
|
|
111
|
+
moveTo(TAGLINE_ROW, 4),
|
|
112
|
+
style.coral("◆◆◆"),
|
|
113
|
+
moveTo(TAGLINE_ROW, TAGLINE_COL),
|
|
114
|
+
style.sand(currentText),
|
|
115
|
+
];
|
|
116
|
+
process.stdout.write(out.join(""));
|
|
117
|
+
};
|
|
118
|
+
const onResize = () => {
|
|
119
|
+
paintFrame();
|
|
120
|
+
};
|
|
121
|
+
// Initial setup.
|
|
122
|
+
process.stdout.write(ALT_SCREEN_ENTER + HIDE_CURSOR);
|
|
123
|
+
try {
|
|
124
|
+
if (process.stdin.isTTY && process.stdin.setRawMode) {
|
|
125
|
+
process.stdin.setRawMode(true);
|
|
126
|
+
}
|
|
127
|
+
process.stdin.resume();
|
|
128
|
+
process.stdin.on("data", onData);
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
/* if raw mode isn't available, we'll only react to SIGINT */
|
|
132
|
+
}
|
|
133
|
+
process.on("SIGINT", stop);
|
|
134
|
+
process.stdout.on("resize", onResize);
|
|
135
|
+
paintFrame();
|
|
136
|
+
// Animation loop.
|
|
46
137
|
(async () => {
|
|
47
138
|
let lastIdx = -1;
|
|
48
139
|
while (!stopped) {
|
|
49
140
|
let idx = Math.floor(Math.random() * TAGLINES.length);
|
|
50
|
-
// Never repeat the previous tagline.
|
|
51
141
|
while (idx === lastIdx) {
|
|
52
142
|
idx = Math.floor(Math.random() * TAGLINES.length);
|
|
53
143
|
}
|
|
54
144
|
lastIdx = idx;
|
|
55
145
|
const tagline = TAGLINES[idx];
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
for (let i = 0; i < tagline.length; i++) {
|
|
146
|
+
// Type out character by character. Repainting the whole frame
|
|
147
|
+
// each tick is overkill, but it's correct under resize and
|
|
148
|
+
// makes the code easier to reason about than tracking partial
|
|
149
|
+
// updates.
|
|
150
|
+
for (let i = 1; i <= tagline.length; i++) {
|
|
62
151
|
if (stopped)
|
|
63
152
|
return;
|
|
64
|
-
|
|
153
|
+
currentText = tagline.slice(0, i);
|
|
154
|
+
paintFrame();
|
|
65
155
|
await sleep(rand(TYPE_MIN_MS, TYPE_MAX_MS));
|
|
66
156
|
}
|
|
67
|
-
// Hold while the natural terminal cursor blinks at the end.
|
|
68
157
|
await sleep(rand(HOLD_MIN_MS, HOLD_MAX_MS));
|
|
69
158
|
if (stopped)
|
|
70
159
|
return;
|
|
71
|
-
|
|
72
|
-
for (let i = tagline.length; i > 0; i--) {
|
|
160
|
+
for (let i = tagline.length - 1; i >= 0; i--) {
|
|
73
161
|
if (stopped)
|
|
74
162
|
return;
|
|
75
|
-
|
|
163
|
+
currentText = tagline.slice(0, i);
|
|
164
|
+
paintFrame();
|
|
76
165
|
await sleep(rand(ERASE_MIN_MS, ERASE_MAX_MS));
|
|
77
166
|
}
|
|
78
|
-
process.stdout.write(RESET);
|
|
79
167
|
await sleep(rand(BETWEEN_MIN_MS, BETWEEN_MAX_MS));
|
|
80
168
|
}
|
|
81
169
|
})().catch(() => {
|
|
82
|
-
/*
|
|
170
|
+
/* never crash the easter egg */
|
|
83
171
|
});
|
|
84
172
|
});
|
|
85
173
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"easter_egg.js","sourceRoot":"","sources":["../../src/cli/easter_egg.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAExC
|
|
1
|
+
{"version":3,"file":"easter_egg.js","sourceRoot":"","sources":["../../src/cli/easter_egg.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -26,7 +26,7 @@ import { tailAudit } from "./cli/tail.js";
|
|
|
26
26
|
import { openPlan } from "./cli/open.js";
|
|
27
27
|
import { showAbout } from "./cli/about.js";
|
|
28
28
|
import { runEasterEgg } from "./cli/easter_egg.js";
|
|
29
|
-
|
|
29
|
+
import { VERSION } from "./lib/version.js";
|
|
30
30
|
/**
|
|
31
31
|
* orqlaude CLI — read-only inspection of state + audit log + Telegram setup
|
|
32
32
|
* and run.
|