@sema-agent/cli 1.0.12 → 1.0.13
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/npm-shrinkwrap.json +5 -5
- package/package.json +3 -3
- package/sema.js +118 -32
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@sema-agent/cli",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.13",
|
|
10
10
|
"license": "BUSL-1.1",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@sema-agent/sdk": "0.0.53",
|
|
@@ -645,9 +645,9 @@
|
|
|
645
645
|
}
|
|
646
646
|
},
|
|
647
647
|
"node_modules/@sema-agent/registry-core": {
|
|
648
|
-
"version": "0.10.
|
|
649
|
-
"resolved": "https://registry.npmjs.org/@sema-agent/registry-core/-/registry-core-0.10.
|
|
650
|
-
"integrity": "sha512-
|
|
648
|
+
"version": "0.10.14",
|
|
649
|
+
"resolved": "https://registry.npmjs.org/@sema-agent/registry-core/-/registry-core-0.10.14.tgz",
|
|
650
|
+
"integrity": "sha512-6EJe0WmrOrnEY/mITs8FHwCbBy5zcUWzRd1QaOYdEPF5H1DGvv/YcowZ4fR9HTWOpa9l8VI5mJv8gJA4EVxD0w==",
|
|
651
651
|
"license": "BUSL-1.1",
|
|
652
652
|
"dependencies": {
|
|
653
653
|
"zod": "^3.24.0"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "Sema — your own Claude Code-grade coding agent, in the terminal.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"bin": {
|
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
},
|
|
27
27
|
"overrides": {
|
|
28
28
|
"@sema-agent/core": "1.309.0",
|
|
29
|
-
"@sema-agent/registry-core": "0.10.
|
|
29
|
+
"@sema-agent/registry-core": "0.10.14"
|
|
30
30
|
},
|
|
31
|
-
"semaEngineVersion": "server 1.218.0 / core 1.309.0 / registry-core 0.10.
|
|
31
|
+
"semaEngineVersion": "server 1.218.0 / core 1.309.0 / registry-core 0.10.14",
|
|
32
32
|
"engines": {
|
|
33
33
|
"node": ">=18"
|
|
34
34
|
}
|
package/sema.js
CHANGED
|
@@ -359913,6 +359913,15 @@ function genericResultText(r, opts) {
|
|
|
359913
359913
|
return typeof bb?.text === "string" ? bb.text : bb?.type === "image" ? "[image]" : "";
|
|
359914
359914
|
}).filter(Boolean).join("\n");
|
|
359915
359915
|
}
|
|
359916
|
+
if (s.trimStart().startsWith("[")) {
|
|
359917
|
+
try {
|
|
359918
|
+
const arr = JSON.parse(s);
|
|
359919
|
+
if (Array.isArray(arr) && arr.length > 0 && arr.every((b3) => b3 && typeof b3 === "object" && (b3.type === "text" || b3.type === "image"))) {
|
|
359920
|
+
s = arr.map((bb) => typeof bb.text === "string" ? bb.text : bb.type === "image" ? "[image]" : "").filter(Boolean).join("\n");
|
|
359921
|
+
}
|
|
359922
|
+
} catch {
|
|
359923
|
+
}
|
|
359924
|
+
}
|
|
359916
359925
|
s = s.trimEnd();
|
|
359917
359926
|
if (!s) return "";
|
|
359918
359927
|
if (opts?.full) return s;
|
|
@@ -359967,7 +359976,7 @@ function UserToolSuccessMessage({
|
|
|
359967
359976
|
if (report) {
|
|
359968
359977
|
renderedMessage = /* @__PURE__ */ (0, import_jsx_runtime118.jsx)(SubagentReportSummary, { report, isTranscriptMode });
|
|
359969
359978
|
} else {
|
|
359970
|
-
const fallbackText = genericResultText(message.toolUseResult);
|
|
359979
|
+
const fallbackText = genericResultText(message.toolUseResult, { full: Boolean(isTranscriptMode) || verbose });
|
|
359971
359980
|
if (fallbackText) renderedMessage = /* @__PURE__ */ (0, import_jsx_runtime118.jsx)(MessageResponse, { children: /* @__PURE__ */ (0, import_jsx_runtime118.jsx)(ThemedText, { children: fallbackText }) });
|
|
359972
359981
|
}
|
|
359973
359982
|
}
|
|
@@ -406129,7 +406138,10 @@ var init_lifetimeMarkers = __esm({
|
|
|
406129
406138
|
|
|
406130
406139
|
// build-src/src/tools/ScheduleCronTool/UI.tsx
|
|
406131
406140
|
function renderCreateToolUseMessage(input) {
|
|
406132
|
-
|
|
406141
|
+
const s = input.schedule;
|
|
406142
|
+
const sched = input.cron ?? (s?.kind === "cron" && typeof s.expr === "string" ? s.expr : s?.kind === "delay" && typeof s.delaySec === "number" ? `in ${s.delaySec}s` : s?.kind === "at" ? `at ${typeof s.at === "string" ? s.at : "\u2026"}` : void 0);
|
|
406143
|
+
const label = input.label ? ` [${input.label}]` : "";
|
|
406144
|
+
return `${sched ?? ""}${label}${input.prompt ? `: ${truncate(input.prompt, 60, true)}` : ""}`;
|
|
406133
406145
|
}
|
|
406134
406146
|
function renderCreateResultMessage(output) {
|
|
406135
406147
|
return /* @__PURE__ */ (0, import_jsx_runtime154.jsx)(MessageResponse, { children: /* @__PURE__ */ (0, import_jsx_runtime154.jsxs)(ThemedText, { children: [
|
|
@@ -406203,10 +406215,17 @@ var init_CronCreateTool = __esm({
|
|
|
406203
406215
|
init_UI24();
|
|
406204
406216
|
MAX_JOBS = 50;
|
|
406205
406217
|
inputSchema35 = lazySchema(
|
|
406206
|
-
() => external_exports.
|
|
406207
|
-
cron: external_exports.string().describe(
|
|
406218
|
+
() => external_exports.object({
|
|
406219
|
+
cron: external_exports.string().optional().describe(
|
|
406208
406220
|
'Standard 5-field cron expression in local time: "M H DoM Mon DoW" (e.g. "*/5 * * * *" = every 5 minutes, "30 14 28 2 *" = Feb 28 at 2:30pm local once).'
|
|
406209
406221
|
),
|
|
406222
|
+
schedule: external_exports.object({
|
|
406223
|
+
kind: external_exports.string().optional(),
|
|
406224
|
+
expr: external_exports.string().optional(),
|
|
406225
|
+
delaySec: external_exports.number().optional(),
|
|
406226
|
+
at: external_exports.string().optional()
|
|
406227
|
+
}).optional().describe("Engine schedule form (kinds cron/at/delay) \u2014 accepted by the live engine tool face."),
|
|
406228
|
+
label: external_exports.string().optional(),
|
|
406210
406229
|
prompt: external_exports.string().describe("The prompt to enqueue at each fire time."),
|
|
406211
406230
|
recurring: semanticBoolean(external_exports.boolean().optional()).describe(
|
|
406212
406231
|
`true (default) = fire on every cron match until deleted or auto-expired after ${DEFAULT_MAX_AGE_DAYS} days. false = fire once at the next match, then auto-delete. Use false for "remind me at X" one-shot requests with pinned minute/hour/dom/month.`
|
|
@@ -406251,6 +406270,13 @@ var init_CronCreateTool = __esm({
|
|
|
406251
406270
|
return getCronFilePath();
|
|
406252
406271
|
},
|
|
406253
406272
|
async validateInput(input) {
|
|
406273
|
+
if (typeof input.cron !== "string" || input.cron.length === 0) {
|
|
406274
|
+
return {
|
|
406275
|
+
result: false,
|
|
406276
|
+
message: "This local CronCreate accepts the 5-field `cron` string form. The `schedule` object form is handled by the live engine tool \u2014 pass `cron` here.",
|
|
406277
|
+
errorCode: 5
|
|
406278
|
+
};
|
|
406279
|
+
}
|
|
406254
406280
|
if (!parseCronExpression(input.cron)) {
|
|
406255
406281
|
return {
|
|
406256
406282
|
result: false,
|
|
@@ -426077,7 +426103,7 @@ var init_BashTool = __esm({
|
|
|
426077
426103
|
init_toolName();
|
|
426078
426104
|
init_UI();
|
|
426079
426105
|
init_utils6();
|
|
426080
|
-
import_jsx_runtime163 = __toESM(require_jsx_runtime());
|
|
426106
|
+
import_jsx_runtime163 = __toESM(require_jsx_runtime(), 1);
|
|
426081
426107
|
EOL5 = "\n";
|
|
426082
426108
|
PROGRESS_THRESHOLD_MS3 = 2e3;
|
|
426083
426109
|
ASSISTANT_BLOCKING_BUDGET_MS2 = 15e3;
|
|
@@ -479492,8 +479518,8 @@ var init_sema_brand = __esm({
|
|
|
479492
479518
|
"Slash-command gating wired to the fleet capability handshake"
|
|
479493
479519
|
]
|
|
479494
479520
|
},
|
|
479495
|
-
productVersion: "1.0.
|
|
479496
|
-
announcement: "sema 1.0.
|
|
479521
|
+
productVersion: "1.0.13",
|
|
479522
|
+
announcement: "sema 1.0.13 \u2014 tool cards render faithfully again (CronCreate headers, skill results, full output behind ctrl+o), and scheduler writes are concurrency-safe across sessions and daemons"
|
|
479497
479523
|
};
|
|
479498
479524
|
}
|
|
479499
479525
|
});
|
|
@@ -482427,8 +482453,8 @@ var require_sema_brand = __commonJS({
|
|
|
482427
482453
|
"Slash-command gating wired to the fleet capability handshake"
|
|
482428
482454
|
]
|
|
482429
482455
|
},
|
|
482430
|
-
productVersion: "1.0.
|
|
482431
|
-
announcement: "sema 1.0.
|
|
482456
|
+
productVersion: "1.0.13",
|
|
482457
|
+
announcement: "sema 1.0.13 \u2014 tool cards render faithfully again (CronCreate headers, skill results, full output behind ctrl+o), and scheduler writes are concurrency-safe across sessions and daemons"
|
|
482432
482458
|
};
|
|
482433
482459
|
}
|
|
482434
482460
|
});
|
|
@@ -496964,6 +496990,7 @@ var init_types19 = __esm({
|
|
|
496964
496990
|
maxTokens: external_exports3.number().int().positive().optional(),
|
|
496965
496991
|
autoCompactTokens: external_exports3.number().int().positive().optional(),
|
|
496966
496992
|
charsPerToken: external_exports3.number().finite().positive().optional(),
|
|
496993
|
+
promptGuidance: external_exports3.array(external_exports3.string()).optional(),
|
|
496967
496994
|
cost: ModelCost.optional(),
|
|
496968
496995
|
extraBody: external_exports3.unknown().optional().transform((v2, ctx) => {
|
|
496969
496996
|
if (v2 === void 0)
|
|
@@ -607537,8 +607564,8 @@ function _temp161() {
|
|
|
607537
607564
|
var import_compiler_runtime316, import_react313, SETTINGS_ERRORS_NOTIFICATION_KEY;
|
|
607538
607565
|
var init_useSettingsErrors = __esm({
|
|
607539
607566
|
"build-src/src/hooks/notifs/useSettingsErrors.tsx"() {
|
|
607540
|
-
import_compiler_runtime316 = __toESM(require_compiler_runtime());
|
|
607541
|
-
import_react313 = __toESM(require_react());
|
|
607567
|
+
import_compiler_runtime316 = __toESM(require_compiler_runtime(), 1);
|
|
607568
|
+
import_react313 = __toESM(require_react(), 1);
|
|
607542
607569
|
init_notifications();
|
|
607543
607570
|
init_state();
|
|
607544
607571
|
init_allErrors();
|
|
@@ -640407,6 +640434,7 @@ async function ensurePrintModeEngine() {
|
|
|
640407
640434
|
}
|
|
640408
640435
|
async function ensureLocalEngineOneShot(label = "one-shot") {
|
|
640409
640436
|
seedUserSettingsEnv();
|
|
640437
|
+
process.env.SCHEDULER_SESSION_WAKEUP ??= "false";
|
|
640410
640438
|
try {
|
|
640411
640439
|
const { applyPersistedTlsTrust: applyPersistedTlsTrust2 } = await Promise.resolve().then(() => (init_tlsTrust(), tlsTrust_exports));
|
|
640412
640440
|
await applyPersistedTlsTrust2();
|
|
@@ -653659,7 +653687,7 @@ Auth: unix socket -R \u2192 local proxy`, "info");
|
|
|
653659
653687
|
pendingHookMessages
|
|
653660
653688
|
}, renderAndRun);
|
|
653661
653689
|
}
|
|
653662
|
-
}).version("sema 1.0.
|
|
653690
|
+
}).version("sema 1.0.13", "-v, --version", "Output the version number");
|
|
653663
653691
|
program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
|
|
653664
653692
|
program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
|
|
653665
653693
|
if (canUserConfigureAdvisor()) {
|
|
@@ -657423,19 +657451,29 @@ var init_schedulerDaemon = __esm({
|
|
|
657423
657451
|
/** Run one tick: fire due intents, persist the rescheduled/reaped record set. Returns the count fired. */
|
|
657424
657452
|
async tickOnce() {
|
|
657425
657453
|
const nowMs = (this.opts.now ?? (() => Date.now()))();
|
|
657426
|
-
let
|
|
657427
|
-
|
|
657428
|
-
|
|
657429
|
-
|
|
657430
|
-
this.opts.
|
|
657431
|
-
|
|
657432
|
-
|
|
657433
|
-
|
|
657434
|
-
|
|
657435
|
-
|
|
657436
|
-
const { toFire, updated } = tickRecords(owned, nowMs);
|
|
657454
|
+
let toFire = [];
|
|
657455
|
+
const computeNext = (all4) => {
|
|
657456
|
+
const owned = [];
|
|
657457
|
+
const foreign = [];
|
|
657458
|
+
for (const r of all4) (this.opts.owns?.(r) ?? true ? owned : foreign).push(r);
|
|
657459
|
+
const t2 = tickRecords(owned, nowMs);
|
|
657460
|
+
toFire = t2.toFire;
|
|
657461
|
+
if (t2.toFire.length === 0 && t2.updated.length === owned.length && t2.updated.every((r, i) => r === owned[i])) return null;
|
|
657462
|
+
return [...t2.updated, ...foreign];
|
|
657463
|
+
};
|
|
657437
657464
|
try {
|
|
657438
|
-
this.store.
|
|
657465
|
+
if (this.store.mutate) {
|
|
657466
|
+
const m2 = this.store.mutate(computeNext);
|
|
657467
|
+
if (!m2.ok && m2.reason !== "aborted") {
|
|
657468
|
+
this.opts.onError?.(new Error(`scheduler store mutate failed: ${m2.reason}`));
|
|
657469
|
+
return 0;
|
|
657470
|
+
}
|
|
657471
|
+
if (!m2.ok) return 0;
|
|
657472
|
+
} else {
|
|
657473
|
+
const next = computeNext(this.store.load());
|
|
657474
|
+
if (next === null) return 0;
|
|
657475
|
+
this.store.save(next);
|
|
657476
|
+
}
|
|
657439
657477
|
} catch (e) {
|
|
657440
657478
|
this.opts.onError?.(e);
|
|
657441
657479
|
return 0;
|
|
@@ -657529,6 +657567,30 @@ function saveSchedulerStore(path27, records) {
|
|
|
657529
657567
|
writeFileSync21(tmp, serializeSchedulerStore(records), { mode: 384 });
|
|
657530
657568
|
renameSync10(tmp, path27);
|
|
657531
657569
|
}
|
|
657570
|
+
function mutateSchedulerStore(path27, fn2, opts) {
|
|
657571
|
+
const maxRetries = Math.max(0, opts?.retries ?? 5);
|
|
657572
|
+
const rawOf = () => {
|
|
657573
|
+
try {
|
|
657574
|
+
return readFileSync51(path27, "utf-8");
|
|
657575
|
+
} catch {
|
|
657576
|
+
return null;
|
|
657577
|
+
}
|
|
657578
|
+
};
|
|
657579
|
+
for (let attempt = 0; ; attempt++) {
|
|
657580
|
+
const baseRaw = rawOf();
|
|
657581
|
+
const records = baseRaw === null ? [] : parseSchedulerStore(baseRaw);
|
|
657582
|
+
const next = fn2(records);
|
|
657583
|
+
if (next === null)
|
|
657584
|
+
return { ok: false, reason: "aborted" };
|
|
657585
|
+
if (rawOf() !== baseRaw) {
|
|
657586
|
+
if (attempt >= maxRetries)
|
|
657587
|
+
return { ok: false, reason: "conflict_exhausted", retries: attempt };
|
|
657588
|
+
continue;
|
|
657589
|
+
}
|
|
657590
|
+
saveSchedulerStore(path27, next);
|
|
657591
|
+
return { ok: true, records: next, retries: attempt };
|
|
657592
|
+
}
|
|
657593
|
+
}
|
|
657532
657594
|
var init_scheduler_store_node = __esm({
|
|
657533
657595
|
"node_modules/@sema-agent/registry-core/dist/scheduler-store-node.js"() {
|
|
657534
657596
|
init_scheduler_store();
|
|
@@ -657570,7 +657632,9 @@ function schedulerStorePath() {
|
|
|
657570
657632
|
function fileSchedulerStoreIO(storePath) {
|
|
657571
657633
|
return {
|
|
657572
657634
|
load: () => loadSchedulerStore(storePath),
|
|
657573
|
-
save: (records) => saveSchedulerStore(storePath, records)
|
|
657635
|
+
save: (records) => saveSchedulerStore(storePath, records),
|
|
657636
|
+
// [1003] 唯一跨进程变更原语绑定:daemon tick/sessionReap/孤儿清扫的写路径全走它。
|
|
657637
|
+
mutate: (fn2) => mutateSchedulerStore(storePath, fn2)
|
|
657574
657638
|
};
|
|
657575
657639
|
}
|
|
657576
657640
|
var init_schedulerDaemonWire = __esm({
|
|
@@ -657599,6 +657663,15 @@ function partitionSessionReap(records, departedSessionIds) {
|
|
|
657599
657663
|
}
|
|
657600
657664
|
function reapSessionRecords(io, departedSessionIds) {
|
|
657601
657665
|
if (departedSessionIds.length === 0) return [];
|
|
657666
|
+
if (io.mutate) {
|
|
657667
|
+
let ids = [];
|
|
657668
|
+
const m2 = io.mutate((records) => {
|
|
657669
|
+
const { kept: kept2, reaped: reaped2 } = partitionSessionReap(records, departedSessionIds);
|
|
657670
|
+
ids = reaped2.map((r) => r.id);
|
|
657671
|
+
return reaped2.length === 0 ? null : kept2;
|
|
657672
|
+
});
|
|
657673
|
+
return m2.ok || !m2.ok && m2.reason === "aborted" ? ids : [];
|
|
657674
|
+
}
|
|
657602
657675
|
const { kept, reaped } = partitionSessionReap(io.load(), departedSessionIds);
|
|
657603
657676
|
if (reaped.length === 0) return [];
|
|
657604
657677
|
io.save(kept);
|
|
@@ -657677,13 +657750,26 @@ function sweepOrphanSessionRecords(io, storePath, opts = {}) {
|
|
|
657677
657750
|
cleanupDead: true
|
|
657678
657751
|
});
|
|
657679
657752
|
for (const id of opts.ownSessionIds ?? []) if (id) claimed.add(id);
|
|
657680
|
-
const
|
|
657681
|
-
|
|
657682
|
-
|
|
657683
|
-
|
|
657684
|
-
|
|
657685
|
-
|
|
657686
|
-
|
|
657753
|
+
const partition3 = (all4) => {
|
|
657754
|
+
const kept2 = [];
|
|
657755
|
+
const reapedIds2 = [];
|
|
657756
|
+
for (const r of all4) {
|
|
657757
|
+
const orphan = isSessionLifetimeRecord(r) && typeof r.sessionId === "string" && r.sessionId.length > 0 && !claimed.has(r.sessionId) && nowMs - r.createdMs > graceMs;
|
|
657758
|
+
if (orphan) reapedIds2.push(r.id);
|
|
657759
|
+
else kept2.push(r);
|
|
657760
|
+
}
|
|
657761
|
+
return { kept: kept2, reapedIds: reapedIds2 };
|
|
657762
|
+
};
|
|
657763
|
+
if (io.mutate) {
|
|
657764
|
+
let ids = [];
|
|
657765
|
+
const m2 = io.mutate((all4) => {
|
|
657766
|
+
const t2 = partition3(all4);
|
|
657767
|
+
ids = t2.reapedIds;
|
|
657768
|
+
return t2.reapedIds.length === 0 ? null : t2.kept;
|
|
657769
|
+
});
|
|
657770
|
+
return m2.ok || !m2.ok && m2.reason === "aborted" ? ids : [];
|
|
657771
|
+
}
|
|
657772
|
+
const { kept, reapedIds } = partition3(records);
|
|
657687
657773
|
if (reapedIds.length > 0) io.save(kept);
|
|
657688
657774
|
return reapedIds;
|
|
657689
657775
|
}
|