iranti 0.2.15 → 0.2.16

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/README.md CHANGED
@@ -9,10 +9,10 @@
9
9
 
10
10
  Iranti gives agents persistent, identity-based memory. Facts written by one agent are retrievable by any other agent through exact entity+key lookup. Iranti also supports hybrid search (lexical + vector) when exact keys are unknown. Memory persists across sessions and survives context window limits.
11
11
 
12
- **Latest release:** [`v0.2.10`](https://github.com/nfemmanuel/iranti/releases/tag/v0.2.10)
12
+ **Latest release:** [`v0.2.16`](https://github.com/nfemmanuel/iranti/releases/tag/v0.2.16)
13
13
  Published packages:
14
- - `iranti@0.2.10`
15
- - `@iranti/sdk@0.2.10`
14
+ - `iranti@0.2.16`
15
+ - `@iranti/sdk@0.2.16`
16
16
 
17
17
  ---
18
18
 
@@ -245,6 +245,18 @@ iranti run --instance local
245
245
 
246
246
  If local PostgreSQL is available, setup can bootstrap a localhost database for you. If local PostgreSQL is not available, setup recommends Docker when Docker is installed, and otherwise steers you to managed PostgreSQL with concrete install guidance.
247
247
 
248
+ Long-running agents can now checkpoint and recover interrupted work. Programmatic session lifecycle methods are available through the SDK and REST API:
249
+ - `checkpoint()`
250
+ - `resumeSession()`
251
+ - `completeSession()`
252
+ - `abandonSession()`
253
+
254
+ Running instances now publish runtime metadata in `/health`, and the CLI can see that state through `iranti status`, `iranti instance show`, and `iranti upgrade --check`. When you want an installed upgrade to immediately take effect on an instance-backed API server, use:
255
+
256
+ ```bash
257
+ iranti upgrade --restart --instance local
258
+ ```
259
+
248
260
  If something still fails and you need more detail, use:
249
261
 
250
262
  ```bash
@@ -20,6 +20,7 @@ const runtimeEnv_1 = require("../src/lib/runtimeEnv");
20
20
  const resolutionist_1 = require("../src/resolutionist");
21
21
  const chat_1 = require("../src/chat");
22
22
  const backends_1 = require("../src/library/backends");
23
+ const runtimeLifecycle_1 = require("../src/lib/runtimeLifecycle");
23
24
  const sdk_1 = require("../src/sdk");
24
25
  class CliError extends Error {
25
26
  constructor(code, message, hints = [], details) {
@@ -454,6 +455,7 @@ function instancePaths(root, name) {
454
455
  instanceDir,
455
456
  envFile: path_1.default.join(instanceDir, '.env'),
456
457
  metaFile: path_1.default.join(instanceDir, 'instance.json'),
458
+ runtimeFile: path_1.default.join(instanceDir, 'runtime.json'),
457
459
  };
458
460
  }
459
461
  async function loadInstanceEnv(root, name) {
@@ -470,6 +472,63 @@ async function loadInstanceEnv(root, name) {
470
472
  env: await readEnvFile(paths.envFile),
471
473
  };
472
474
  }
475
+ async function readInstanceRuntimeSummary(root, name) {
476
+ const { runtimeFile } = instancePaths(root, name);
477
+ const state = await (0, runtimeLifecycle_1.readRuntimeState)(runtimeFile);
478
+ if (!state) {
479
+ return { state: null, running: false, stale: false };
480
+ }
481
+ const running = (0, runtimeLifecycle_1.isPidRunning)(state.pid);
482
+ return {
483
+ state,
484
+ running,
485
+ stale: !running && state.status !== 'stopped',
486
+ };
487
+ }
488
+ function describeInstanceRuntime(summary) {
489
+ if (!summary.state) {
490
+ return `${warnLabel('STOPPED')} no runtime metadata`;
491
+ }
492
+ if (summary.running) {
493
+ return `${okLabel('RUNNING')} pid=${summary.state.pid} version=${summary.state.version}`;
494
+ }
495
+ if (summary.stale) {
496
+ return `${warnLabel('STALE')} last_pid=${summary.state.pid} version=${summary.state.version}`;
497
+ }
498
+ return `${warnLabel('STOPPED')} version=${summary.state.version}`;
499
+ }
500
+ async function startInstanceRuntime(name, instanceDir, envFile, runtimeFile) {
501
+ process.env.IRANTI_INSTANCE_NAME = name;
502
+ process.env.IRANTI_INSTANCE_DIR = instanceDir;
503
+ process.env.IRANTI_INSTANCE_RUNTIME_FILE = runtimeFile;
504
+ process.env.IRANTI_INSTANCE_ENV_FILE = envFile;
505
+ console.log(`${infoLabel()} Starting Iranti instance '${name}' on port ${process.env.IRANTI_PORT ?? '3001'}...`);
506
+ const serverEntry = path_1.default.resolve(__dirname, '..', 'src', 'api', 'server');
507
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
508
+ require(serverEntry);
509
+ }
510
+ async function stopRuntimeProcess(pid, timeoutMs) {
511
+ if (!(0, runtimeLifecycle_1.isPidRunning)(pid))
512
+ return true;
513
+ try {
514
+ process.kill(pid, 'SIGTERM');
515
+ }
516
+ catch {
517
+ if (process.platform === 'win32') {
518
+ const proc = runCommandCapture('taskkill', ['/PID', String(pid), '/T']);
519
+ if (proc.status !== 0) {
520
+ return false;
521
+ }
522
+ }
523
+ else {
524
+ return false;
525
+ }
526
+ }
527
+ if (await (0, runtimeLifecycle_1.waitForPidExit)(pid, timeoutMs)) {
528
+ return true;
529
+ }
530
+ return false;
531
+ }
473
532
  async function resolveProviderKeyTarget(args) {
474
533
  const scope = normalizeScope(getFlag(args, 'scope'));
475
534
  const explicitInstance = getFlag(args, 'instance');
@@ -1751,6 +1810,63 @@ function runCommandInteractive(step) {
1751
1810
  });
1752
1811
  return proc.status;
1753
1812
  }
1813
+ function currentCliInvocation() {
1814
+ const argv1 = process.argv[1] ? path_1.default.resolve(process.argv[1]) : '';
1815
+ const forwardedDebug = CLI_DEBUG ? ['--debug'] : [];
1816
+ const forwardedVerbose = !CLI_DEBUG && CLI_VERBOSE ? ['--verbose'] : [];
1817
+ if (argv1.endsWith('.ts')) {
1818
+ return {
1819
+ executable: 'npx',
1820
+ args: ['ts-node', argv1, ...forwardedDebug, ...forwardedVerbose],
1821
+ };
1822
+ }
1823
+ return {
1824
+ executable: process.execPath,
1825
+ args: argv1 ? [argv1, ...forwardedDebug, ...forwardedVerbose] : [...forwardedDebug, ...forwardedVerbose],
1826
+ };
1827
+ }
1828
+ function spawnDetachedCli(args, cwd) {
1829
+ const invocation = currentCliInvocation();
1830
+ const child = (0, child_process_1.spawn)(invocation.executable, [...invocation.args, ...args], {
1831
+ detached: true,
1832
+ stdio: 'ignore',
1833
+ windowsHide: true,
1834
+ cwd: cwd ?? process.cwd(),
1835
+ env: process.env,
1836
+ });
1837
+ child.unref();
1838
+ return child.pid ?? 0;
1839
+ }
1840
+ async function restartInstanceRuntime(args, instanceName, scope, root) {
1841
+ const runtimeBefore = await readInstanceRuntimeSummary(root, instanceName);
1842
+ if (!runtimeBefore.running || !runtimeBefore.state?.pid) {
1843
+ throw cliError('IRANTI_INSTANCE_NOT_RUNNING', `Instance '${instanceName}' is not currently running.`, [`Start it with \`iranti run --instance ${instanceName}\` before requesting a restart.`], { instance: instanceName, root, runtimePresent: Boolean(runtimeBefore.state), pid: runtimeBefore.state?.pid ?? null });
1844
+ }
1845
+ const timeoutSeconds = Number.parseInt(getFlag(args, 'graceful-timeout') ?? '20', 10);
1846
+ const timeoutMs = Number.isFinite(timeoutSeconds) && timeoutSeconds > 0 ? timeoutSeconds * 1000 : 20000;
1847
+ const previousPid = runtimeBefore.state?.pid ?? null;
1848
+ if (previousPid) {
1849
+ console.log(`${infoLabel()} Stopping instance '${instanceName}' (pid ${previousPid})...`);
1850
+ const stopped = await stopRuntimeProcess(previousPid, timeoutMs);
1851
+ if (!stopped) {
1852
+ throw cliError('IRANTI_INSTANCE_STOP_TIMEOUT', `Instance '${instanceName}' did not stop within ${timeoutSeconds}s.`, ['Close the process manually or rerun with a longer --graceful-timeout.'], { instance: instanceName, pid: previousPid, timeoutSeconds });
1853
+ }
1854
+ }
1855
+ const newPid = spawnDetachedCli([
1856
+ 'run',
1857
+ '--instance',
1858
+ instanceName,
1859
+ '--scope',
1860
+ scope,
1861
+ '--root',
1862
+ root,
1863
+ ], root);
1864
+ return {
1865
+ previousPid,
1866
+ newPid,
1867
+ runtimeBefore,
1868
+ };
1869
+ }
1754
1870
  function deriveDatabaseUrlForMode(mode, instanceName, explicitDatabaseUrl) {
1755
1871
  if (explicitDatabaseUrl && !detectPlaceholder(explicitDatabaseUrl)) {
1756
1872
  return explicitDatabaseUrl.trim();
@@ -2089,10 +2205,10 @@ async function chooseInteractiveUpgradeTargets(statuses) {
2089
2205
  });
2090
2206
  return selected;
2091
2207
  }
2092
- async function executeUpgradeTargets(targets, context) {
2208
+ async function executeUpgradeTargets(targets, context, options = {}) {
2093
2209
  const results = [];
2094
2210
  for (const target of targets) {
2095
- const result = await executeUpgradeTarget(target, context);
2211
+ const result = await executeUpgradeTarget(target, context, options);
2096
2212
  results.push(result);
2097
2213
  }
2098
2214
  return results;
@@ -2167,7 +2283,7 @@ function resolveDetachedUpgradeCwd(command) {
2167
2283
  }
2168
2284
  return normalized;
2169
2285
  }
2170
- function scheduleDetachedWindowsGlobalNpmUpgrade(command) {
2286
+ function scheduleDetachedWindowsGlobalNpmUpgrade(command, postCommand) {
2171
2287
  const neutralCwd = resolveDetachedUpgradeCwd(command);
2172
2288
  const parentPid = process.pid;
2173
2289
  const powershell = 'powershell.exe';
@@ -2179,6 +2295,7 @@ function scheduleDetachedWindowsGlobalNpmUpgrade(command) {
2179
2295
  'while (Get-Process -Id $parentPid -ErrorAction SilentlyContinue) { Start-Sleep -Milliseconds 500 }',
2180
2296
  `Set-Location -LiteralPath '${escapedCwd}'`,
2181
2297
  `& '${escapedExecutable}' @(${escapedArgs})`,
2298
+ ...(postCommand ? [`if ($LASTEXITCODE -eq 0) { ${postCommand} }`] : []),
2182
2299
  'exit $LASTEXITCODE',
2183
2300
  ].join('; ');
2184
2301
  const child = (0, child_process_1.spawn)(powershell, ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', script], {
@@ -2196,7 +2313,7 @@ function verifyPythonInstall(command) {
2196
2313
  ? { status: 'pass', detail: `Python client Version: ${version}.` }
2197
2314
  : { status: 'warn', detail: 'Python upgrade finished, but installed version could not be confirmed.' };
2198
2315
  }
2199
- async function executeUpgradeTarget(target, context) {
2316
+ async function executeUpgradeTarget(target, context, options = {}) {
2200
2317
  if (target === 'npm-repo' && repoIsDirty(context.packageRootPath)) {
2201
2318
  throw new Error('Repository worktree is dirty. Commit or stash changes before running `iranti upgrade --target npm-repo --yes`.');
2202
2319
  }
@@ -2205,7 +2322,7 @@ async function executeUpgradeTarget(target, context) {
2205
2322
  if (target === 'npm-global' && canScheduleWindowsGlobalNpmSelfUpgrade(context)) {
2206
2323
  const command = commands[0];
2207
2324
  console.log(`${infoLabel()} ${command.display} (scheduled in a detached updater because the current Windows CLI cannot replace its own live global install)`);
2208
- scheduleDetachedWindowsGlobalNpmUpgrade(command);
2325
+ scheduleDetachedWindowsGlobalNpmUpgrade(command, options.detachedPostCommand);
2209
2326
  steps.push({ label: `${command.label} (detached)`, command: command.display });
2210
2327
  return {
2211
2328
  target,
@@ -2912,6 +3029,7 @@ async function statusCommand(args) {
2912
3029
  name: entry.name,
2913
3030
  port,
2914
3031
  envFile: fs_1.default.existsSync(envFile) ? envFile : '(missing)',
3032
+ runtime: await readInstanceRuntimeSummary(root, entry.name),
2915
3033
  });
2916
3034
  }
2917
3035
  }
@@ -2940,8 +3058,48 @@ async function statusCommand(args) {
2940
3058
  for (const instance of instances) {
2941
3059
  console.log(` - ${instance.name} (port ${instance.port})`);
2942
3060
  console.log(` env: ${instance.envFile}`);
3061
+ if (instance.runtime.state) {
3062
+ const runtimeLabel = instance.runtime.running
3063
+ ? `${okLabel('RUNNING')} pid=${instance.runtime.state.pid} version=${instance.runtime.state.version}`
3064
+ : instance.runtime.stale
3065
+ ? `${warnLabel('STALE')} last_pid=${instance.runtime.state.pid} version=${instance.runtime.state.version}`
3066
+ : `${warnLabel('STOPPED')} version=${instance.runtime.state.version}`;
3067
+ console.log(` runtime: ${runtimeLabel}`);
3068
+ console.log(` health: ${instance.runtime.state.healthUrl}`);
3069
+ }
3070
+ else {
3071
+ console.log(` runtime: ${warnLabel('STOPPED')} no runtime metadata`);
3072
+ }
3073
+ }
3074
+ }
3075
+ }
3076
+ async function collectRuntimeInstanceSummaries(root) {
3077
+ const instancesDir = path_1.default.join(root, 'instances');
3078
+ const instances = [];
3079
+ if (!fs_1.default.existsSync(instancesDir)) {
3080
+ return instances;
3081
+ }
3082
+ const entries = await promises_1.default.readdir(instancesDir, { withFileTypes: true });
3083
+ for (const entry of entries.filter((value) => value.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
3084
+ const envFile = path_1.default.join(instancesDir, entry.name, '.env');
3085
+ let port = '(unknown)';
3086
+ if (fs_1.default.existsSync(envFile)) {
3087
+ try {
3088
+ const env = await readEnvFile(envFile);
3089
+ port = env.IRANTI_PORT ?? '(unknown)';
3090
+ }
3091
+ catch {
3092
+ port = '(unreadable)';
3093
+ }
2943
3094
  }
3095
+ instances.push({
3096
+ name: entry.name,
3097
+ port,
3098
+ envFile: fs_1.default.existsSync(envFile) ? envFile : '(missing)',
3099
+ runtime: await readInstanceRuntimeSummary(root, entry.name),
3100
+ });
2944
3101
  }
3102
+ return instances;
2945
3103
  }
2946
3104
  async function upgradeCommand(args) {
2947
3105
  const runAll = hasFlag(args, 'all');
@@ -2986,8 +3144,18 @@ async function upgradeCommand(args) {
2986
3144
  python: context.pythonVersion && latestPython ? compareVersions(latestPython, context.pythonVersion) > 0 : null,
2987
3145
  };
2988
3146
  const plan = selectedTargets.flatMap((target) => commandListForTarget(target, context).map((step) => step.display));
3147
+ const runtimeInstances = await collectRuntimeInstanceSummaries(context.runtimeRoot);
3148
+ const runningRuntimeInstances = runtimeInstances.filter((instance) => instance.runtime.running);
3149
+ const restartRequiredInstances = runningRuntimeInstances.filter((instance) => {
3150
+ const version = instance.runtime.state?.version;
3151
+ return Boolean(version && version !== context.currentVersion);
3152
+ });
3153
+ const detachedRestartCommand = hasFlag(args, 'restart') && getFlag(args, 'instance')
3154
+ ? `& 'iranti' instance restart '${escapeForSingleQuotedPowerShell(getFlag(args, 'instance'))}' --scope '${normalizeScope(getFlag(args, 'scope'))}' --root '${escapeForSingleQuotedPowerShell(resolveInstallRoot(args, normalizeScope(getFlag(args, 'scope'))))}'`
3155
+ : undefined;
2989
3156
  let execution = [];
2990
3157
  let note = null;
3158
+ let restartSummary = null;
2991
3159
  if (execute) {
2992
3160
  if (selectedTargets.length === 0) {
2993
3161
  throw new Error('No executable upgrade path was detected. Use --target npm-global, --target npm-repo, --target python, or --all.');
@@ -2996,7 +3164,35 @@ async function upgradeCommand(args) {
2996
3164
  note = 'Execution skipped because --dry-run or --check was provided.';
2997
3165
  }
2998
3166
  else {
2999
- execution = await executeUpgradeTargets(selectedTargets, context);
3167
+ execution = await executeUpgradeTargets(selectedTargets, context, {
3168
+ detachedPostCommand: detachedRestartCommand,
3169
+ });
3170
+ if (hasFlag(args, 'restart')) {
3171
+ const instanceName = getFlag(args, 'instance');
3172
+ if (!instanceName) {
3173
+ throw cliError('IRANTI_INSTANCE_NAME_REQUIRED', 'Missing --instance <name>. Usage: iranti upgrade --yes --restart --instance <name>', ['Pass the running instance name you want restarted after upgrade.']);
3174
+ }
3175
+ const scope = normalizeScope(getFlag(args, 'scope'));
3176
+ const root = resolveInstallRoot(args, scope);
3177
+ const detachedHandled = execution.some((result) => result.target === 'npm-global'
3178
+ && result.verification.status === 'warn'
3179
+ && result.verification.detail.includes('Scheduled detached npm global upgrade'));
3180
+ if (!detachedHandled) {
3181
+ const restarted = await restartInstanceRuntime(args, instanceName, scope, root);
3182
+ restartSummary = {
3183
+ instanceName,
3184
+ newPid: restarted.newPid,
3185
+ previousPid: restarted.previousPid,
3186
+ };
3187
+ }
3188
+ else {
3189
+ restartSummary = {
3190
+ instanceName,
3191
+ newPid: 0,
3192
+ previousPid: null,
3193
+ };
3194
+ }
3195
+ }
3000
3196
  }
3001
3197
  }
3002
3198
  else if (!checkOnly && !dryRun && !json && process.stdin.isTTY && process.stdout.isTTY) {
@@ -3031,6 +3227,9 @@ async function upgradeCommand(args) {
3031
3227
  pythonLauncher: context.python?.executable ?? null,
3032
3228
  pythonVersion: context.pythonVersion,
3033
3229
  },
3230
+ runtimeInstances,
3231
+ runningRuntimeInstances,
3232
+ restartRequiredInstances,
3034
3233
  requestedTargets,
3035
3234
  selectedTargets,
3036
3235
  availableTargets: context.availableTargets,
@@ -3040,6 +3239,7 @@ async function upgradeCommand(args) {
3040
3239
  plan,
3041
3240
  action: execution.length > 0 ? 'upgrade' : checkOnly ? 'check' : dryRun ? 'dry-run' : 'inspect',
3042
3241
  execution,
3242
+ restartSummary,
3043
3243
  note,
3044
3244
  }, null, 2));
3045
3245
  return;
@@ -3057,6 +3257,20 @@ async function upgradeCommand(args) {
3057
3257
  }
3058
3258
  console.log(` python ${context.python?.executable ?? paint('not found', 'yellow')}${context.pythonVersion ? ` (${context.pythonVersion})` : ''}`);
3059
3259
  console.log('');
3260
+ if (runningRuntimeInstances.length > 0) {
3261
+ console.log(' running_instances');
3262
+ for (const instance of runningRuntimeInstances) {
3263
+ const state = instance.runtime.state;
3264
+ const versionLabel = state.version === context.currentVersion
3265
+ ? paint(state.version, 'green')
3266
+ : paint(`${state.version} != ${context.currentVersion}`, 'yellow');
3267
+ console.log(` - ${instance.name} pid=${state.pid} port=${instance.port} version=${versionLabel}`);
3268
+ }
3269
+ if (restartRequiredInstances.length > 0) {
3270
+ console.log(` restart_required ${paint(restartRequiredInstances.map((instance) => instance.name).join(', '), 'yellow')}`);
3271
+ }
3272
+ console.log('');
3273
+ }
3060
3274
  if (selectedTargets.length > 0) {
3061
3275
  console.log(` selected_target${selectedTargets.length > 1 ? 's' : ''} ${paint(selectedTargets.join(', '), 'cyan')}${requestedTargets.includes('auto') ? paint(' (auto)', 'gray') : ''}`);
3062
3276
  console.log(' plan');
@@ -3083,6 +3297,10 @@ async function upgradeCommand(args) {
3083
3297
  console.log(`${okLabel()} Upgrade completed for ${result.target}.`);
3084
3298
  console.log(`${marker} ${result.verification.detail}`);
3085
3299
  }
3300
+ if (restartSummary) {
3301
+ console.log(`${okLabel()} Restart scheduled for instance '${restartSummary.instanceName}'.`);
3302
+ console.log(`${infoLabel()} previous_pid=${restartSummary.previousPid ?? 'none'} new_pid=${restartSummary.newPid || '(unknown)'}`);
3303
+ }
3086
3304
  const { envFile } = resolveDoctorEnvTarget(args);
3087
3305
  if (envFile) {
3088
3306
  console.log(`${infoLabel()} Run \`iranti doctor\` to verify the active environment after the package upgrade.`);
@@ -3196,11 +3414,13 @@ async function listInstancesCommand(args) {
3196
3414
  console.log(bold(`Instances (${instancesDir}):`));
3197
3415
  for (const name of dirs) {
3198
3416
  const metaPath = path_1.default.join(instancesDir, name, 'instance.json');
3417
+ const runtime = await readInstanceRuntimeSummary(root, name);
3199
3418
  if (fs_1.default.existsSync(metaPath)) {
3200
3419
  try {
3201
3420
  const raw = await promises_1.default.readFile(metaPath, 'utf-8');
3202
3421
  const meta = JSON.parse(raw);
3203
3422
  console.log(` - ${name} (port ${meta.port})`);
3423
+ console.log(` runtime: ${describeInstanceRuntime(runtime)}`);
3204
3424
  continue;
3205
3425
  }
3206
3426
  catch {
@@ -3208,6 +3428,7 @@ async function listInstancesCommand(args) {
3208
3428
  }
3209
3429
  }
3210
3430
  console.log(` - ${name}`);
3431
+ console.log(` runtime: ${describeInstanceRuntime(runtime)}`);
3211
3432
  }
3212
3433
  }
3213
3434
  async function showInstanceCommand(args) {
@@ -3221,12 +3442,17 @@ async function showInstanceCommand(args) {
3221
3442
  if (!fs_1.default.existsSync(envFile))
3222
3443
  throw new Error(`Instance '${name}' not found at ${instanceDir}`);
3223
3444
  const env = await readEnvFile(envFile);
3445
+ const runtime = await readInstanceRuntimeSummary(root, name);
3224
3446
  console.log(bold(`Instance: ${name}`));
3225
3447
  console.log(` dir : ${instanceDir}`);
3226
3448
  console.log(` env : ${envFile}`);
3227
3449
  console.log(` port: ${env.IRANTI_PORT ?? '3001'}`);
3228
3450
  console.log(` db : ${env.DATABASE_URL ?? '(missing)'}`);
3229
3451
  console.log(` esc : ${env.IRANTI_ESCALATION_DIR ?? '(missing)'}`);
3452
+ console.log(` runtime: ${describeInstanceRuntime(runtime)}`);
3453
+ if (runtime.state?.healthUrl) {
3454
+ console.log(` health: ${runtime.state.healthUrl}`);
3455
+ }
3230
3456
  console.log(`${infoLabel()} Run with: iranti run --instance ${name}`);
3231
3457
  }
3232
3458
  async function runInstanceCommand(args) {
@@ -3236,21 +3462,48 @@ async function runInstanceCommand(args) {
3236
3462
  }
3237
3463
  const scope = normalizeScope(getFlag(args, 'scope'));
3238
3464
  const root = resolveInstallRoot(args, scope);
3239
- const envFile = path_1.default.join(root, 'instances', name, '.env');
3465
+ const { instanceDir, envFile, runtimeFile } = instancePaths(root, name);
3240
3466
  if (!fs_1.default.existsSync(envFile)) {
3241
3467
  throw cliError('IRANTI_INSTANCE_NOT_FOUND', `Instance '${name}' not found. Create it first.`, [`Run \`iranti setup\` or \`iranti instance create ${name}\` first.`], { instance: name, envFile });
3242
3468
  }
3243
3469
  const env = await readEnvFile(envFile);
3470
+ const runtime = await readInstanceRuntimeSummary(root, name);
3471
+ if (runtime.running) {
3472
+ throw cliError('IRANTI_INSTANCE_ALREADY_RUNNING', `Instance '${name}' is already running on pid ${runtime.state?.pid ?? '(unknown)'}.`, [`Run \`iranti instance restart ${name}\` to restart the live process, or stop the existing process first.`], { instance: name, pid: runtime.state?.pid ?? null, runtimeFile });
3473
+ }
3474
+ if (runtime.stale) {
3475
+ console.log(`${warnLabel()} Found stale runtime metadata for '${name}' at ${runtimeFile}; starting a fresh process.`);
3476
+ }
3244
3477
  for (const [k, v] of Object.entries(env)) {
3245
3478
  process.env[k] = v;
3246
3479
  }
3247
3480
  if (!process.env.DATABASE_URL || process.env.DATABASE_URL.includes('yourpassword')) {
3248
3481
  throw cliError('IRANTI_INSTANCE_DATABASE_PLACEHOLDER', `Instance '${name}' has placeholder DATABASE_URL. Edit ${envFile} first.`, ['Run `iranti configure instance <name> --interactive` or rerun `iranti setup`.'], { instance: name, envFile });
3249
3482
  }
3250
- console.log(`${infoLabel()} Starting Iranti instance '${name}' on port ${process.env.IRANTI_PORT ?? '3001'}...`);
3251
- const serverEntry = path_1.default.resolve(__dirname, '..', 'src', 'api', 'server');
3252
- // eslint-disable-next-line @typescript-eslint/no-var-requires
3253
- require(serverEntry);
3483
+ await startInstanceRuntime(name, instanceDir, envFile, runtimeFile);
3484
+ }
3485
+ async function restartInstanceCommand(args) {
3486
+ const name = getFlag(args, 'instance') ?? args.positionals[0] ?? args.subcommand;
3487
+ if (!name) {
3488
+ throw cliError('IRANTI_INSTANCE_NAME_REQUIRED', 'Missing instance name. Usage: iranti instance restart <name>', ['Run `iranti instance list` to see configured instances.']);
3489
+ }
3490
+ const scope = normalizeScope(getFlag(args, 'scope'));
3491
+ const root = resolveInstallRoot(args, scope);
3492
+ const { envFile } = await loadInstanceEnv(root, name);
3493
+ const restarted = await restartInstanceRuntime(args, name, scope, root);
3494
+ console.log(sectionTitle('Instance Restart Scheduled'));
3495
+ console.log(` status ${okLabel()}`);
3496
+ console.log(` instance ${name}`);
3497
+ console.log(` env ${envFile}`);
3498
+ if (restarted.previousPid) {
3499
+ console.log(` previous ${restarted.previousPid}`);
3500
+ }
3501
+ console.log(` new_pid ${restarted.newPid || '(unknown)'}`);
3502
+ console.log(` runtime ${restarted.runtimeBefore.running ? 'was running' : restarted.runtimeBefore.state ? 'was stale/stopped' : 'no prior runtime metadata'}`);
3503
+ printNextSteps([
3504
+ `iranti status --scope ${scope}${root ? ` --root "${root}"` : ''}`,
3505
+ `iranti doctor --instance ${name}${root ? ` --root "${root}"` : ''}`,
3506
+ ]);
3254
3507
  }
3255
3508
  async function projectInitCommand(args) {
3256
3509
  const projectPath = path_1.default.resolve(args.positionals[0] ?? process.cwd());
@@ -3799,7 +4052,7 @@ async function chatCommand(args) {
3799
4052
  function printHelp() {
3800
4053
  const rows = [
3801
4054
  ['iranti setup', 'Guided first-run setup. Best place to start.'],
3802
- ['iranti run --instance local', 'Start a configured instance.'],
4055
+ ['iranti run --instance local', 'Start a configured instance and record runtime metadata.'],
3803
4056
  ['iranti doctor', 'Check env, database, provider keys, and runtime health.'],
3804
4057
  ['iranti chat', 'Open the local Iranti chat shell.'],
3805
4058
  ];
@@ -3822,8 +4075,9 @@ function printHelp() {
3822
4075
  ['iranti setup [--scope user|system] [--root <path>] [--mode isolated|shared] [--instance <name>] [--port <n>] [--config <file> | --defaults] [--db-mode local|managed|docker] [--db-url <url>] [--provider <name>] [--api-key <token>] [--projects <path1,path2>] [--claude-code] [--bootstrap-db]', 'Guided setup for runtime, database, instance, keys, and project binding. Run iranti setup --help for the non-interactive flow.'],
3823
4076
  ['iranti instance create <name> [--port 3001] [--db-url <url>] [--api-key <token>] [--provider <name>] [--provider-key <token>] [--scope user|system]', 'Create an instance directly if you want low-level control.'],
3824
4077
  ['iranti instance list [--scope user|system]', 'List configured instances.'],
3825
- ['iranti instance show <name> [--scope user|system]', 'Show one instance env, port, and database target.'],
3826
- ['iranti run --instance <name> [--scope user|system]', 'Start an instance.'],
4078
+ ['iranti instance show <name> [--scope user|system]', 'Show one instance env, port, database target, and runtime state.'],
4079
+ ['iranti instance restart <name> [--scope user|system] [--graceful-timeout <seconds>]', 'Restart a running instance using its runtime metadata.'],
4080
+ ['iranti run --instance <name> [--scope user|system]', 'Start an instance and write runtime metadata.'],
3827
4081
  ]);
3828
4082
  printRows('Configuration', [
3829
4083
  ['iranti configure instance <name> [--interactive] [--db-url <url>] [--port <n>] [--api-key <token>] [--provider <name>] [--provider-key <token>] [--clear-provider-key] [--json]', 'Update an instance without editing env files manually.'],
@@ -3886,6 +4140,7 @@ function printInstanceHelp() {
3886
4140
  console.log(` ${commandText('iranti instance create <name> [--port 3001] [--db-url <url>] [--api-key <token>] [--provider <name>] [--provider-key <token>] [--scope user|system] [--root <path>]')}`);
3887
4141
  console.log(` ${commandText('iranti instance list [--scope user|system] [--root <path>]')}`);
3888
4142
  console.log(` ${commandText('iranti instance show <name> [--scope user|system] [--root <path>]')}`);
4143
+ console.log(` ${commandText('iranti instance restart <name> [--scope user|system] [--root <path>] [--graceful-timeout <seconds>]')}`);
3889
4144
  }
3890
4145
  function printConfigureHelp() {
3891
4146
  console.log(sectionTitle('Configure Commands'));
@@ -3954,6 +4209,10 @@ async function main() {
3954
4209
  await showInstanceCommand(args);
3955
4210
  return;
3956
4211
  }
4212
+ if (args.subcommand === 'restart') {
4213
+ await restartInstanceCommand(args);
4214
+ return;
4215
+ }
3957
4216
  throw new Error(`Unknown instance subcommand '${args.subcommand ?? ''}'.`);
3958
4217
  }
3959
4218
  if (args.command === 'run') {
@@ -144,7 +144,7 @@ async function main() {
144
144
  await ensureDefaultAgent(iranti);
145
145
  const server = new mcp_js_1.McpServer({
146
146
  name: 'iranti-mcp',
147
- version: '0.2.15',
147
+ version: '0.2.16',
148
148
  });
149
149
  server.registerTool('iranti_handshake', {
150
150
  description: `Initialize or refresh an agent's working-memory brief for the current task.
@@ -90,6 +90,50 @@ declare const schemas: {
90
90
  maxLength: number;
91
91
  };
92
92
  };
93
+ checkpoint: {
94
+ agentId: {
95
+ type: string;
96
+ required: boolean;
97
+ maxLength: number;
98
+ };
99
+ task: {
100
+ type: string;
101
+ required: boolean;
102
+ maxLength: number;
103
+ };
104
+ recentMessages: {
105
+ type: string;
106
+ required: boolean;
107
+ maxLength: number;
108
+ };
109
+ checkpoint: {
110
+ type: string;
111
+ required: boolean;
112
+ maxSize: number;
113
+ };
114
+ sessionId: {
115
+ type: string;
116
+ required: boolean;
117
+ maxLength: number;
118
+ };
119
+ heartbeatAt: {
120
+ type: string;
121
+ required: boolean;
122
+ maxLength: number;
123
+ };
124
+ };
125
+ sessionAction: {
126
+ agentId: {
127
+ type: string;
128
+ required: boolean;
129
+ maxLength: number;
130
+ };
131
+ sessionId: {
132
+ type: string;
133
+ required: boolean;
134
+ maxLength: number;
135
+ };
136
+ };
93
137
  relate: {
94
138
  fromEntity: {
95
139
  type: string;
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../../src/api/middleware/validation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG1D,QAAA,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCZ,CAAC;AAwDF,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,OAAO,OAAO,IACpD,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,oDAmCxD;AAGD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOlD;AAGD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEtD;AAGD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEhD"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../../src/api/middleware/validation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG1D,QAAA,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkDZ,CAAC;AAwDF,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,OAAO,OAAO,IACpD,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,oDAmCxD;AAGD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOlD;AAGD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEtD;AAGD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEhD"}
@@ -31,6 +31,18 @@ const schemas = {
31
31
  task: { type: 'string', required: true, maxLength: 1000 },
32
32
  recentMessages: { type: 'array', required: false, maxLength: 100 }
33
33
  },
34
+ checkpoint: {
35
+ agentId: { type: 'string', required: true, maxLength: 200 },
36
+ task: { type: 'string', required: true, maxLength: 1000 },
37
+ recentMessages: { type: 'array', required: true, maxLength: 100 },
38
+ checkpoint: { type: 'any', required: true, maxSize: 20000 },
39
+ sessionId: { type: 'string', required: false, maxLength: 200 },
40
+ heartbeatAt: { type: 'string', required: false, maxLength: 50 }
41
+ },
42
+ sessionAction: {
43
+ agentId: { type: 'string', required: true, maxLength: 200 },
44
+ sessionId: { type: 'string', required: false, maxLength: 200 }
45
+ },
34
46
  relate: {
35
47
  fromEntity: { type: 'string', required: true, pattern: /^[a-zA-Z0-9_-]+\/[a-zA-Z0-9_/-]+$/, maxLength: 200 },
36
48
  toEntity: { type: 'string', required: true, pattern: /^[a-zA-Z0-9_-]+\/[a-zA-Z0-9_/-]+$/, maxLength: 200 },
@@ -1 +1 @@
1
- {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../../src/api/middleware/validation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../../src/api/middleware/validation.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../../src/api/routes/memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAyCnC,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAmHnD"}
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../../src/api/routes/memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAyCnC,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAsKnD"}