gipity 1.0.396 → 1.0.397

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.
@@ -1,17 +1,18 @@
1
1
  import { Command } from 'commander';
2
2
  import { sync } from '../sync.js';
3
3
  import { createProgressReporter } from '../progress.js';
4
- import { error as clrError } from '../colors.js';
4
+ import { error as clrError, muted } from '../colors.js';
5
5
  export const syncCommand = new Command('sync')
6
6
  .description('Sync files (a .gipityignore at the project root excludes paths, gitignore-style)')
7
7
  .option('--plan', 'Print the plan without applying any changes')
8
8
  .option('--force', 'Bypass the bulk-deletion guard')
9
+ .option('--prune', 'Remove files that exist on Gipity but not locally (applies the bulk deletes the guard defers)')
9
10
  .option('--json', 'Output as JSON')
10
11
  .action(async (opts) => {
11
12
  try {
12
13
  // JSON mode stays machine-clean; otherwise show live progress on a TTY.
13
14
  const progress = opts.json ? undefined : createProgressReporter();
14
- const result = await sync({ plan: opts.plan, force: opts.force, progress });
15
+ const result = await sync({ plan: opts.plan, force: opts.force, prune: opts.prune, progress });
15
16
  if (opts.json) {
16
17
  console.log(JSON.stringify(result));
17
18
  }
@@ -20,8 +21,14 @@ export const syncCommand = new Command('sync')
20
21
  if (!opts.plan && result.applied > 0) {
21
22
  console.log(`\n${result.applied} action${result.applied > 1 ? 's' : ''} applied.`);
22
23
  }
23
- if (result.skipped > 0) {
24
- console.error(clrError(`${result.skipped} action${result.skipped > 1 ? 's' : ''} skipped by guard.`));
24
+ // The guard defers bulk server-side deletes (files on Gipity but not
25
+ // local). Surface that here as a helpful hint - not a red error - with
26
+ // the one command that resolves it. Only `gipity sync` shows this;
27
+ // deploy/test/sandbox stay silent (their internal sync defers quietly).
28
+ if (result.deferredDeletes > 0) {
29
+ console.log(muted(`\n${result.deferredDeletes} file${result.deferredDeletes > 1 ? 's' : ''} on Gipity ` +
30
+ `${result.deferredDeletes > 1 ? 'are' : 'is'} not present locally and ${result.deferredDeletes > 1 ? 'were' : 'was'} left untouched. ` +
31
+ `Run 'gipity sync --prune' to remove ${result.deferredDeletes > 1 ? 'them' : 'it'}.`));
25
32
  }
26
33
  for (const e of result.errors)
27
34
  console.error(clrError(e));
package/dist/knowledge.js CHANGED
@@ -45,7 +45,7 @@ Gipity is the cloud platform your project runs on - hosting, databases, deployme
45
45
 
46
46
  Prefer the cheapest option that works - CLI and sandbox are instant and free, app services are runtime HTTP calls, \`gipity chat\` burns LLM tokens:
47
47
 
48
- 1. CLI commands (fast, no agent overhead). The \`gipity\` CLI covers add, deploy, db, fn, logs, browser, sync, memory, skill, and more. All commands support \`--json\`.
48
+ 1. CLI commands (fast, no agent overhead). The \`gipity\` CLI covers add, deploy, db, fn, logs, browser, sync, memory, skill, email, and more. All commands support \`--json\`. You can send email yourself - \`gipity email send\` goes out as the agent from \`gipity@gipity.ai\` with no setup or API keys (\`gipity skill read email\`); don't build a \`mailto:\` workaround or reach for an SMTP library.
49
49
  2. Cloud sandbox via \`gipity sandbox run\` - Docker container with pre-installed tools for media (ffmpeg, ImageMagick, sox), documents (pandoc, LibreOffice), and data (pandas, matplotlib, sqlite3). Run \`gipity skill read sandbox-tools\` for the full toolkit. No network from inside the sandbox - fetch what you need before sending it in.
50
50
  3. App services - runtime HTTP endpoints your deployed app calls directly at \`https://a.gipity.ai/api/<PROJECT_GUID>/services/*\`. Available: LLM, TTS, image, sound, music, transcribe, video, file upload, realtime, location. Load the matching skill (\`app-llm\`, \`app-tts\`, etc.) before writing service code - they have the schemas, auth pattern, and common-mistake guards. For one-off generation during development, prefer \`gipity generate <image|video|speech|music>\` or \`gipity chat\`. \`gipity generate\` saves to a generic file in the current directory by default (e.g. \`./generated.png\`) - pass \`-o <path>\` to write it straight into your source tree so it deploys (e.g. \`gipity generate image "hero banner" -o src/assets/images/hero.png\`) instead of generating at cwd and moving it.
51
51
  4. Delegate to Gip (\`gipity chat "<task>"\`) - only when the work genuinely needs agent reasoning or a tool not in the CLI, sandbox, or app services. Required for: Twitter/X search, Gmail, calendar, push notifications, video understanding, audio source isolation, cross-model second opinions, multi-step orchestration. Don't use \`gipity chat\` for anything the sandbox can do - it's slower and burns tokens.
@@ -54,7 +54,7 @@ You are the developer. Write files in this directory - the Gipity Claude Code pl
54
54
 
55
55
  ## Use first-party services before reaching outside
56
56
 
57
- Gipity ships first-party services for what apps usually pull from third parties - auth, location/geocoding, LLM, image/audio/video generation, transcription, file uploads, realtime. Before calling an external API or adding an npm package for one of these, check \`gipity skill list\` for a match. First-party services need no API keys, cost less, and keep data in-house. Reach outside only when the catalog has no equivalent - and say so when you do.
57
+ Gipity ships first-party services for what apps usually pull from third parties - auth, location/geocoding, LLM, image/audio/video generation, transcription, file uploads, realtime, and email (send as the agent via \`gipity email send\`, or from a deployed app via a workflow \`notify\` step - no SMTP/SendGrid/Nodemailer). Before calling an external API or adding an npm package for one of these, check \`gipity skill list\` for a match. First-party services need no API keys, cost less, and keep data in-house. Reach outside only when the catalog has no equivalent - and say so when you do.
58
58
 
59
59
  ## Don't guess Gipity facts - look them up
60
60
 
@@ -98,7 +98,7 @@ mkdir -p ~/GipityProjects/<slug> && cd ~/GipityProjects/<slug> && gipity init <s
98
98
 
99
99
  ## CLI quick reference
100
100
 
101
- Key commands: \`gipity add <template|kit>\`, \`gipity deploy dev\`, \`gipity sandbox run\`, \`gipity page inspect <url>\`, \`gipity page screenshot <url>\`, \`gipity db query "SQL"\`, \`gipity fn call <name>\`, \`gipity logs fn <name>\`, \`gipity skill read <name>\`.
101
+ Key commands: \`gipity add <template|kit>\`, \`gipity deploy dev\`, \`gipity sandbox run\`, \`gipity page inspect <url>\`, \`gipity page screenshot <url>\`, \`gipity db query "SQL"\`, \`gipity fn call <name>\`, \`gipity logs fn <name>\`, \`gipity email send --to <addr> --subject <s> --body <b>\` (sends as \`gipity@gipity.ai\`; omit \`--to\` to self-send), \`gipity skill read <name>\`.
102
102
  Pull an existing remote project local (given its URL/slug): \`mkdir -p ~/GipityProjects/<slug> && cd ~/GipityProjects/<slug> && gipity init <slug>\` (adopts the matching project and syncs files down - this is the "clone").
103
103
  For deterministic text questions (letter/word counts, substring occurrences, nth word/char, anagrams), use \`gipity text analyze "<text>"\` - local and instant, no sandbox or LLM needed.
104
104
  Run \`gipity --help\` for the full list. Use \`--help\` on any command for details.
@@ -149,6 +149,7 @@ Kit skills (reusable building blocks - \`gipity add <kit>\`):
149
149
  - \`chatbot\` - the chatbot kit: persona + scope guardrails + static knowledge, bubble widget or headless engine
150
150
 
151
151
  Other key skills:
152
+ - \`email\` - sending email as the agent from gipity@gipity.ai (no setup/keys) — plus Gmail-thread replies, HTML formatting, images
152
153
  - \`sandbox-tools\` - cloud sandbox capabilities and pre-installed tools
153
154
  - \`tts\` - agent-side speech tools (different from the \`app-tts\` HTTP service)`;
154
155
  export const DEFINITION_OF_DONE = `## Definition of done (build tasks)
package/dist/sync.js CHANGED
@@ -481,16 +481,20 @@ async function bulkDeleteGuard(p, knownFiles, opts) {
481
481
  const totalDeletes = p.deletesLocal + p.deletesRemote;
482
482
  if (totalDeletes === 0)
483
483
  return true;
484
- if (opts.force)
484
+ if (opts.force || opts.prune)
485
485
  return true;
486
486
  const denom = Math.max(knownFiles, 1);
487
487
  const fraction = totalDeletes / denom;
488
488
  if (totalDeletes < BULK_DELETE_COUNT || fraction < BULK_DELETE_FRACTION)
489
489
  return true;
490
490
  if (!opts.interactive || getAutoConfirm()) {
491
- console.error(`Refusing to delete ${totalDeletes} file${totalDeletes > 1 ? 's' : ''} ` +
492
- `(${Math.round(fraction * 100)}% of tree) non-interactively. ` +
493
- `Re-run with --force or interactively to confirm.`);
491
+ // Non-interactive (deploy/test/sandbox auto-mirror): there's no human to
492
+ // confirm, so defer the bulk deletes SILENTLY and carry them forward. This
493
+ // is the safe default - uploads/downloads still apply, nothing is deleted -
494
+ // and it avoids spamming a "Refusing to delete N files" error on every
495
+ // command when a project legitimately has server-only files (e.g. runtime
496
+ // uploads, or sandbox outputs not kept locally). The deferred count rides
497
+ // out in SyncResult.deferredDeletes; `gipity sync --prune` applies them.
494
498
  return false;
495
499
  }
496
500
  const answer = await prompt(`\nPlan deletes ${totalDeletes} files (${Math.round(fraction * 100)}% of the tree). Type "delete" to confirm: `);
@@ -572,6 +576,7 @@ async function syncInner(projectGuid, root, ignore, opts, interactive) {
572
576
  return {
573
577
  plan: planned, applied: 0, skipped: 0, errors: [],
574
578
  summary: formatPlan(planned),
579
+ deferredDeletes: 0,
575
580
  };
576
581
  }
577
582
  // Bulk-delete guard over the *planned* deletes.
@@ -983,6 +988,7 @@ async function syncInner(projectGuid, root, ignore, opts, interactive) {
983
988
  skipped: skippedByGuard,
984
989
  errors,
985
990
  summary: formatPlan(planned),
991
+ deferredDeletes: skippedByGuard,
986
992
  };
987
993
  }
988
994
  function cleanupEmptyDirs(root, ignorePatterns) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gipity",
3
- "version": "1.0.396",
3
+ "version": "1.0.397",
4
4
  "description": "The full-stack platform tuned for AI agents. Database, storage, auth, functions, deploy, and drop-in kits - all agent-tuned. Pair with Claude Code or use standalone.",
5
5
  "bin": {
6
6
  "gipity": "dist/updater/shim.js",