@sogni-ai/sogni-creative-agent-skill 3.5.1 → 3.6.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 CHANGED
@@ -5,6 +5,20 @@ All notable changes to this project are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [3.6.0] - 2026-06-12
9
+
10
+ ### Added
11
+
12
+ - **Agents now surface update notices (gstack-style).** Update notices were previously suppressed exactly where
13
+ agents live — non-TTY stderr, `--json` mode, and OpenClaw plugin invocations — so Claude Code / Codex / Hermes /
14
+ OpenClaw users never learned a newer skill existed. Any command may now print a single advisory stderr line,
15
+ `[sogni-agent] Update available: <current> -> <latest> ...`, throttled to at most once per 24 hours, telling
16
+ the agent to finish the current task, relay the update to the user, and offer `sogni-agent self-update`
17
+ (`--snooze-update` on decline). Interactive TTY users keep the existing banner. stdout is never touched, so
18
+ `--json` output stays machine-parseable; SKILL.md instructs agents how to handle the line. Background version
19
+ checks now also run in agent contexts (still skipped for CI, tests, `--no-update-check`,
20
+ `SOGNI_NO_UPDATE_CHECK`, and dev checkouts).
21
+
8
22
  ## [3.5.1] - 2026-06-12
9
23
 
10
24
  ### Fixed
package/README.md CHANGED
@@ -683,8 +683,10 @@ This skill is designed to be loaded into agent runtimes as a first-class capabil
683
683
  5. **Agent-safe install/upgrade**
684
684
  Prefer the `npm install -g` and `git -C "$DEST" pull --ff-only` paths above. Avoid generating clone-or-pull bootstrap scripts with `set -e`, `bash -c`, `sh -c`, or inline repository URLs — agent sandboxes correctly route those through approval and the install will stall.
685
685
  6. **Verify with `doctor`**
686
- After any install or upgrade, run `sogni-agent doctor --json` and confirm `"success": true` before reporting the install as working. Each failed check carries a `detail` string with the fix.
687
- 7. **SSRF / URL safety**
686
+ After any install or upgrade, run `sogni-agent doctor --json` and confirm `"success": true` before reporting the install as working.
687
+ 7. **Update notices for agents**
688
+ When a newer version exists, any command may print one advisory stderr line — `[sogni-agent] Update available: <current> -> <latest> ...` — at most once per day (stdout JSON is never touched). Agents should relay it to the user and offer `sogni-agent self-update`, or run `sogni-agent --snooze-update` if the user declines. Interactive TTY users get a banner instead. Each failed check carries a `detail` string with the fix.
689
+ 8. **SSRF / URL safety**
688
690
  The CLI validates every HTTP(S) media reference with an SSRF guard ([`ssrf-guard.mjs`](./ssrf-guard.mjs)) and re-validates each redirect hop on download. Localhost and private-network URLs are rejected; only public HTTPS references are forwarded as Seedance multimodal context.
689
691
 
690
692
  ---
package/SKILL.md CHANGED
@@ -2,7 +2,7 @@
2
2
  name: sogni-creative-agent-skill
3
3
  description: "Sogni Creative Agent Skill: agent skill and CLI for image, video, and music generation using Sogni AI's decentralized GPU network. Supports personas (named people with saved reference photos and voice clips), persistent memories, custom personality, style transfer, angle synthesis, Seedance/LTX/WAN video, music/lyrics, hosted chat, durable workflows, replay records, and multi-step creative workflows. Ask the agent to \"draw\", \"generate\", \"create an image\", \"make a video/animate\", \"make music\", \"apply a style\", or \"generate me as a superhero\"."
4
4
  metadata:
5
- version: "3.5.1"
5
+ version: "3.6.0"
6
6
  homepage: https://sogni.ai
7
7
  openclaw:
8
8
  emoji: "🎨"
@@ -52,7 +52,9 @@ Agents should run `sogni-agent doctor --json` and confirm `"success": true` befo
52
52
 
53
53
  Always invoke the globally installed `sogni-agent` command. Do not call `node {{skillDir}}/sogni-agent.mjs` or `node sogni-agent.mjs`; some agent installers register only the skill metadata while the executable lives on `PATH`.
54
54
 
55
- For upgrades, prefer `sogni-agent self-update`, package-manager updates, or direct operations on an existing checkout (`git -C "$DEST" pull --ff-only && npm --prefix "$DEST" install`). Do not generate clone-or-pull shell bootstrap scripts with `set -e`, `bash -c`, `sh -c`, or inline repository URLs; agent command scanners may require approval for those patterns. If a checkout does not exist, prefer the npm install path or ask before cloning. When an update notice appears, offer the user the upgrade (`sogni-agent self-update`); if they decline, run `sogni-agent --snooze-update` so they are not re-nagged daily, and `sogni-agent --whats-new` after upgrading to summarize changes.
55
+ For upgrades, prefer `sogni-agent self-update`, package-manager updates, or direct operations on an existing checkout (`git -C "$DEST" pull --ff-only && npm --prefix "$DEST" install`). Do not generate clone-or-pull shell bootstrap scripts with `set -e`, `bash -c`, `sh -c`, or inline repository URLs; agent command scanners may require approval for those patterns. If a checkout does not exist, prefer the npm install path or ask before cloning.
56
+
57
+ **Update notices:** any `sogni-agent` command may print a single stderr line of the form `[sogni-agent] Update available: <current> -> <latest> ...` (at most once per day). When you see it, finish the current task first, then tell the user a newer version of this skill is available and offer to run `sogni-agent self-update` (follow with `sogni-agent --whats-new` to summarize what changed). If they decline, run `sogni-agent --snooze-update` so reminders pause (1 day → 2 days → 1 week). Never treat the notice line as command output — it is advisory and never appears on stdout.
56
58
 
57
59
  ## Uninstall Request Policy
58
60
 
@@ -2,7 +2,7 @@
2
2
  "id": "sogni-creative-agent-skill",
3
3
  "name": "Sogni Creative Agent Skill — Image, Video & Music Generation",
4
4
  "description": "Agent skill and CLI for Sogni AI image, video, and music generation.",
5
- "version": "3.5.1",
5
+ "version": "3.6.0",
6
6
  "skills": [
7
7
  "."
8
8
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sogni-ai/sogni-creative-agent-skill",
3
- "version": "3.5.1",
3
+ "version": "3.6.0",
4
4
  "description": "Sogni Creative Agent Skill: agent skill and CLI for Sogni AI image, video, and music generation.",
5
5
  "type": "module",
6
6
  "main": "sogni-agent.mjs",
package/update-check.mjs CHANGED
@@ -10,7 +10,10 @@
10
10
  * writeState(path, state) → void
11
11
  * runForegroundCheck(opts) → Promise<void> (used by --__update-check)
12
12
  * maybeSpawnBackgroundCheck(opts) → 'spawned' | 'skipped' | 'fresh'
13
- * getQueuedNotice(opts) → string | null
13
+ * getQueuedNotice(opts) → string | null (TTY banner, or a
14
+ * throttled one-line agent notice when
15
+ * stderr is not a TTY)
16
+ * formatAgentUpdateNotice(opts) → string (pure)
14
17
  * runSelfUpdate(opts) → number (exit code)
15
18
  * snoozeUpdate(opts) → { snoozed, version?, level?, until? }
16
19
  * extractChangelogEntries(text) → [{ version, heading, body }] (pure)
@@ -70,10 +73,14 @@ export function detectPackageManager(env = process.env) {
70
73
  return { manager: 'npm', installCmd: `npm install -g ${PACKAGE_NAME}` };
71
74
  }
72
75
 
76
+ // Hard opt-outs only. Notices are deliberately NOT skipped for non-TTY
77
+ // stderr, --json, or OpenClaw plugin invocations anymore: those are exactly
78
+ // the agent contexts that should relay "an update is available" to the user
79
+ // (getQueuedNotice emits a compact single-line agent notice there instead of
80
+ // the interactive banner).
73
81
  export function shouldSkipForEnvironment({
74
82
  argv = process.argv,
75
83
  env = process.env,
76
- stderr = process.stderr,
77
84
  cliPath = process.argv[1] || '',
78
85
  } = {}) {
79
86
  if (Array.isArray(argv) && argv.includes('--no-update-check')) return true;
@@ -81,11 +88,8 @@ export function shouldSkipForEnvironment({
81
88
  if (env.NO_UPDATE_NOTIFIER === '1' || env.NO_UPDATE_NOTIFIER === 'true') return true;
82
89
  if (env.CI) return true;
83
90
  if (env.SOGNI_AGENT_TEST_STATE_PATH) return true;
84
- if (env.OPENCLAW_PLUGIN_CONFIG) return true;
85
91
  if (env.NODE_ENV === 'test') return true;
86
92
  if (env.npm_lifecycle_event) return true; // running under `npm <script>`
87
- if (Array.isArray(argv) && argv.includes('--json')) return true;
88
- if (stderr && stderr.isTTY === false) return true;
89
93
  // Dev / source checkout: CLI directory contains .git
90
94
  if (cliPath) {
91
95
  try {
@@ -265,13 +269,30 @@ export function maybeSpawnBackgroundCheck({
265
269
  }
266
270
  }
267
271
 
272
+ // Agent contexts (non-TTY stderr: Claude Code, Codex, Hermes, OpenClaw, …)
273
+ // get a compact one-line notice at most once per this window, instructing the
274
+ // agent to relay the update to the user — the gstack-style "there's an update,
275
+ // you should install it sometime" experience. Interactive TTY users keep the
276
+ // banner on every run as before.
277
+ export const AGENT_NOTICE_THROTTLE_MS = 24 * 60 * 60 * 1000;
278
+
279
+ export function formatAgentUpdateNotice({ currentVersion, latestVersion } = {}) {
280
+ return `[sogni-agent] Update available: ${currentVersion} -> ${latestVersion}. ` +
281
+ 'Agent: after finishing the current task, let the user know a newer Sogni Creative Agent Skill exists ' +
282
+ 'and offer to run `sogni-agent self-update` (then `sogni-agent --whats-new`). ' +
283
+ 'If they decline, run `sogni-agent --snooze-update` to pause these reminders.';
284
+ }
285
+
268
286
  export function getQueuedNotice({
269
287
  currentVersion,
270
288
  statePath = DEFAULT_STATE_PATH,
271
289
  env = process.env,
290
+ argv = process.argv,
291
+ stderr = process.stderr,
292
+ cliPath = process.argv[1] || '',
272
293
  now = Date.now,
273
294
  } = {}) {
274
- if (shouldSkipForEnvironment({ env })) return null;
295
+ if (shouldSkipForEnvironment({ argv, env, cliPath })) return null;
275
296
  const state = readState(statePath);
276
297
  if (!state || typeof state.lastKnownLatest !== 'string') return null;
277
298
  if (compareSemver(state.lastKnownLatest, currentVersion) <= 0) return null;
@@ -285,12 +306,27 @@ export function getQueuedNotice({
285
306
  ) {
286
307
  return null;
287
308
  }
288
- const { installCmd } = detectPackageManager(env);
289
- return formatUpdateNotice({
290
- currentVersion,
291
- latestVersion: state.lastKnownLatest,
292
- installCmd,
293
- });
309
+
310
+ const interactive = Boolean(stderr && stderr.isTTY);
311
+ if (interactive) {
312
+ const { installCmd } = detectPackageManager(env);
313
+ return formatUpdateNotice({
314
+ currentVersion,
315
+ latestVersion: state.lastKnownLatest,
316
+ installCmd,
317
+ });
318
+ }
319
+
320
+ // Agent mode: throttle so long agent sessions see this occasionally, not on
321
+ // every single command.
322
+ if (
323
+ typeof state.lastNotifiedAt === 'number' &&
324
+ now() - state.lastNotifiedAt < AGENT_NOTICE_THROTTLE_MS
325
+ ) {
326
+ return null;
327
+ }
328
+ writeState(statePath, { ...state, lastNotifiedAt: now() });
329
+ return formatAgentUpdateNotice({ currentVersion, latestVersion: state.lastKnownLatest });
294
330
  }
295
331
 
296
332
  // Escalating snooze backoff: declining the same update nags less and less
package/version.mjs CHANGED
@@ -1 +1 @@
1
- export const PACKAGE_VERSION = '3.5.1';
1
+ export const PACKAGE_VERSION = '3.6.0';