@aiaiai-pt/martha-cli 0.63.2 → 0.65.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/CHANGELOG.md +17 -0
- package/dist/index.js +59 -9
- package/package.json +1 -1
- package/skills/martha-cli/SKILL.md +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@aiaiai-pt/martha-cli`. Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). This project adheres to semver — `0.x` releases may include breaking changes between minor versions.
|
|
4
4
|
|
|
5
|
+
## [0.65.0] — 2026-10-24
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- `martha documents lifecycle <id>` says where a document's recorded history starts: for a document created before the lifecycle ledger existed it prints "Recorded from <time>; earlier transitions were not recorded", so a short or empty history no longer reads as "nothing happened". It prints nothing extra when the history reaches the document's creation, or against a server that does not send `history_complete` (#1685).
|
|
10
|
+
|
|
11
|
+
## [0.64.0] — 2026-10-20
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- `martha documents lifecycle <id>` explains ingestion, storage and presence states, search eligibility, event permissions, linked source freshness and transition history. `--json` returns the API payload unchanged. Requires a server with the document lifecycle endpoint (#1685).
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Store-only `skipped` ingestion finishes `--wait` and `--follow` successfully.
|
|
20
|
+
- Failed ingestion returns a nonzero exit from JSON wait mode, matching text mode.
|
|
21
|
+
|
|
5
22
|
## [0.63.2] — 2026-10-15
|
|
6
23
|
|
|
7
24
|
### Changed
|
package/dist/index.js
CHANGED
|
@@ -11244,7 +11244,7 @@ init_config();
|
|
|
11244
11244
|
init_errors();
|
|
11245
11245
|
|
|
11246
11246
|
// src/version.ts
|
|
11247
|
-
var CLI_VERSION = "0.
|
|
11247
|
+
var CLI_VERSION = "0.65.0";
|
|
11248
11248
|
|
|
11249
11249
|
// src/commands/sessions.ts
|
|
11250
11250
|
function relativeTime(iso) {
|
|
@@ -17720,7 +17720,44 @@ var triggersConfig = {
|
|
|
17720
17720
|
// src/commands/documents.ts
|
|
17721
17721
|
import fs10 from "node:fs";
|
|
17722
17722
|
init_errors();
|
|
17723
|
-
|
|
17723
|
+
|
|
17724
|
+
// src/lib/document-lifecycle.ts
|
|
17725
|
+
function formatDocumentLifecycle(value) {
|
|
17726
|
+
const lines = [
|
|
17727
|
+
`Document: ${value.document_id}`,
|
|
17728
|
+
`Searchable: ${value.searchable ? "yes" : "no"}`,
|
|
17729
|
+
...value.searchability_reasons.map((reason) => ` ${reason}`)
|
|
17730
|
+
];
|
|
17731
|
+
for (const region of value.regions) {
|
|
17732
|
+
lines.push(`
|
|
17733
|
+
${region.kind}: ${region.state ?? "Not recorded"} (${region.mode})`);
|
|
17734
|
+
for (const event of region.events) {
|
|
17735
|
+
lines.push(` ${event.event} → ${event.to_state}: ${event.allowed ? "allowed" : `unavailable (${event.reason ?? "not authorized"})`}`);
|
|
17736
|
+
}
|
|
17737
|
+
}
|
|
17738
|
+
lines.push(`
|
|
17739
|
+
Sync sources:`);
|
|
17740
|
+
if (!value.sync_sources.length)
|
|
17741
|
+
lines.push(" None");
|
|
17742
|
+
for (const source of value.sync_sources) {
|
|
17743
|
+
lines.push(` ${source.id}: ${source.provider}, ${source.status}; last synced ${source.last_synced_at ?? "never"}`);
|
|
17744
|
+
}
|
|
17745
|
+
lines.push(`
|
|
17746
|
+
History:`);
|
|
17747
|
+
if (value.history_complete === false) {
|
|
17748
|
+
lines.push(value.history_recorded_from ? ` Recorded from ${value.history_recorded_from}; earlier transitions were not recorded` : " Earlier transitions were not recorded");
|
|
17749
|
+
}
|
|
17750
|
+
if (!value.history.length)
|
|
17751
|
+
lines.push(" No recorded transitions");
|
|
17752
|
+
for (const row of value.history) {
|
|
17753
|
+
lines.push(` ${row.seq} ${row.created_at} ${row.kind}: ${row.from_state ?? "∅"} → ${row.to_state} (${row.event}, ${row.actor_kind}:${row.actor_id ?? "unknown"})`);
|
|
17754
|
+
}
|
|
17755
|
+
return lines.join(`
|
|
17756
|
+
`);
|
|
17757
|
+
}
|
|
17758
|
+
|
|
17759
|
+
// src/commands/documents.ts
|
|
17760
|
+
var TERMINAL_STATUSES2 = new Set(["ready", "error", "skipped"]);
|
|
17724
17761
|
var SPINNER_FRAMES2 = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
17725
17762
|
var spinnerIdx = 0;
|
|
17726
17763
|
function nextSpinner() {
|
|
@@ -17850,6 +17887,8 @@ Detached. Check status with: martha documents status ${documentId}`));
|
|
|
17850
17887
|
if (TERMINAL_STATUSES2.has(status.ingestion_status)) {
|
|
17851
17888
|
if (status.ingestion_status === "ready") {
|
|
17852
17889
|
lines.push(source_default.green("Ingestion complete"));
|
|
17890
|
+
} else if (status.ingestion_status === "skipped") {
|
|
17891
|
+
lines.push("Ingestion skipped (store-only document)");
|
|
17853
17892
|
} else {
|
|
17854
17893
|
lines.push(source_default.red(`Error: ${status.error ?? "unknown error"}`));
|
|
17855
17894
|
}
|
|
@@ -17869,6 +17908,8 @@ Detached. Check status with: martha documents status ${documentId}`));
|
|
|
17869
17908
|
if (!isJson && !isTTY) {
|
|
17870
17909
|
if (status.ingestion_status === "ready") {
|
|
17871
17910
|
console.log(`Ingestion complete. ${status.chunk_count ?? 0} chunks created.`);
|
|
17911
|
+
} else if (status.ingestion_status === "skipped") {
|
|
17912
|
+
console.log("Ingestion skipped (store-only document).");
|
|
17872
17913
|
} else {
|
|
17873
17914
|
console.error(`Ingestion failed: ${status.error ?? "unknown error"}`);
|
|
17874
17915
|
process.exitCode = 1 /* Error */;
|
|
@@ -17898,6 +17939,10 @@ function registerDocumentCommands(program) {
|
|
|
17898
17939
|
function isJson() {
|
|
17899
17940
|
return !!program.opts().json;
|
|
17900
17941
|
}
|
|
17942
|
+
cmd.command("lifecycle <document-id>").description("Explain document states, search eligibility, event permissions and history").action(async (documentId) => {
|
|
17943
|
+
const value = await getCtx().api.get(`/api/admin/documents/${encodeURIComponent(documentId)}/lifecycle`);
|
|
17944
|
+
console.log(isJson() ? JSON.stringify(value, null, 2) : formatDocumentLifecycle(value));
|
|
17945
|
+
});
|
|
17901
17946
|
async function resolveCollection(ctx, ref) {
|
|
17902
17947
|
const looksLikeUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(ref);
|
|
17903
17948
|
if (looksLikeUuid) {
|
|
@@ -18124,11 +18169,15 @@ ${items.length} collections`));
|
|
|
18124
18169
|
console.log(source_default.dim(`Uploaded ${result.filename}. Waiting for ingestion...`));
|
|
18125
18170
|
}
|
|
18126
18171
|
const final = await pollIngestionUntilDone(ctx, result.id);
|
|
18172
|
+
if (final.ingestion_status === "error")
|
|
18173
|
+
process.exitCode = 1 /* Error */;
|
|
18127
18174
|
if (isJson()) {
|
|
18128
18175
|
console.log(JSON.stringify(final));
|
|
18129
18176
|
} else {
|
|
18130
18177
|
if (final.ingestion_status === "ready") {
|
|
18131
18178
|
console.log(`Ingestion complete. ${final.chunk_count ?? 0} chunks created.`);
|
|
18179
|
+
} else if (final.ingestion_status === "skipped") {
|
|
18180
|
+
console.log("Ingestion skipped (store-only document).");
|
|
18132
18181
|
} else {
|
|
18133
18182
|
console.error(`Ingestion failed: ${final.error ?? "unknown error"}`);
|
|
18134
18183
|
process.exitCode = 1 /* Error */;
|
|
@@ -18307,11 +18356,15 @@ ${items.length} documents`));
|
|
|
18307
18356
|
console.log(source_default.dim(`Re-ingestion triggered. Waiting for completion...`));
|
|
18308
18357
|
}
|
|
18309
18358
|
const final = await pollIngestionUntilDone(ctx, documentId);
|
|
18359
|
+
if (final.ingestion_status === "error")
|
|
18360
|
+
process.exitCode = 1 /* Error */;
|
|
18310
18361
|
if (isJson()) {
|
|
18311
18362
|
console.log(JSON.stringify(final));
|
|
18312
18363
|
} else {
|
|
18313
18364
|
if (final.ingestion_status === "ready") {
|
|
18314
18365
|
console.log(`Ingestion complete. ${final.chunk_count ?? 0} chunks created.`);
|
|
18366
|
+
} else if (final.ingestion_status === "skipped") {
|
|
18367
|
+
console.log("Ingestion skipped (store-only document).");
|
|
18315
18368
|
} else {
|
|
18316
18369
|
console.error(`Ingestion failed: ${final.error ?? "unknown error"}`);
|
|
18317
18370
|
process.exitCode = 1 /* Error */;
|
|
@@ -20507,13 +20560,10 @@ function registerMessagingCommands(program) {
|
|
|
20507
20560
|
});
|
|
20508
20561
|
cmd.command("send-sms").description("Send a test SMS").requiredOption("--to <number>", "Destination phone number (E.164)").requiredOption("--from <sender>", "Sender ID or number").requiredOption("--content <text>", "Message content").action(async (opts) => {
|
|
20509
20562
|
const ctx = getCtx();
|
|
20510
|
-
const data = await
|
|
20511
|
-
|
|
20512
|
-
|
|
20513
|
-
|
|
20514
|
-
from_number: opts.from,
|
|
20515
|
-
content: opts.content
|
|
20516
|
-
}
|
|
20563
|
+
const data = await ctx.api.post("/api/messaging/send/sms", {
|
|
20564
|
+
to: opts.to,
|
|
20565
|
+
from_number: opts.from,
|
|
20566
|
+
content: opts.content
|
|
20517
20567
|
});
|
|
20518
20568
|
if (isJson()) {
|
|
20519
20569
|
console.log(JSON.stringify(data, null, 2));
|
package/package.json
CHANGED
|
@@ -640,6 +640,7 @@ martha documents move-collection <id> --parent <slug-or-id> | --root # Atomic m
|
|
|
640
640
|
martha documents upload <collection-id> <file> [--wait] [--follow] # --follow streams ingestion progress
|
|
641
641
|
martha documents list <collection-id> [--inactive] [--limit 50]
|
|
642
642
|
martha documents get <doc-id> # Full metadata + chunk count
|
|
643
|
+
martha documents lifecycle <doc-id> [--json] # States, search eligibility, event permissions, sources and history
|
|
643
644
|
martha documents status <doc-id> [--follow] # Ingestion progress: validate → parse → embed → finalize
|
|
644
645
|
martha documents download <doc-id> [--expires 3600] # Presigned URL (default 1h)
|
|
645
646
|
martha documents delete <doc-id> [--yes]
|