atris 2.6.3 → 3.0.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.
Files changed (54) hide show
  1. package/README.md +124 -34
  2. package/atris/CLAUDE.md +5 -1
  3. package/atris/atris.md +4 -0
  4. package/atris/features/README.md +24 -0
  5. package/atris/skills/autopilot/SKILL.md +74 -75
  6. package/atris/skills/endgame/SKILL.md +179 -0
  7. package/atris/skills/flow/SKILL.md +121 -0
  8. package/atris/skills/improve/SKILL.md +84 -0
  9. package/atris/skills/loop/SKILL.md +72 -0
  10. package/atris/skills/wiki/SKILL.md +61 -0
  11. package/atris/team/executor/MEMBER.md +10 -4
  12. package/atris/team/navigator/MEMBER.md +2 -0
  13. package/atris/team/validator/MEMBER.md +8 -5
  14. package/atris.md +33 -0
  15. package/bin/atris.js +210 -41
  16. package/commands/activate.js +28 -2
  17. package/commands/align.js +720 -0
  18. package/commands/auth.js +75 -2
  19. package/commands/autopilot.js +1213 -270
  20. package/commands/browse.js +100 -0
  21. package/commands/business.js +785 -12
  22. package/commands/clean.js +107 -2
  23. package/commands/computer.js +429 -0
  24. package/commands/context-sync.js +78 -8
  25. package/commands/experiments.js +351 -0
  26. package/commands/feedback.js +150 -0
  27. package/commands/fleet.js +395 -0
  28. package/commands/fork.js +127 -0
  29. package/commands/init.js +50 -1
  30. package/commands/learn.js +407 -0
  31. package/commands/lifecycle.js +94 -0
  32. package/commands/loop.js +114 -0
  33. package/commands/publish.js +129 -0
  34. package/commands/pull.js +369 -38
  35. package/commands/push.js +283 -246
  36. package/commands/review.js +149 -0
  37. package/commands/run.js +76 -43
  38. package/commands/serve.js +360 -0
  39. package/commands/setup.js +1 -1
  40. package/commands/soul.js +381 -0
  41. package/commands/status.js +119 -1
  42. package/commands/sync.js +147 -1
  43. package/commands/terminal.js +201 -0
  44. package/commands/wiki.js +376 -0
  45. package/commands/workflow.js +191 -74
  46. package/commands/workspace-clean.js +3 -3
  47. package/lib/endstate.js +259 -0
  48. package/lib/learnings.js +235 -0
  49. package/lib/manifest.js +1 -0
  50. package/lib/todo.js +9 -5
  51. package/lib/wiki.js +578 -0
  52. package/package.json +2 -2
  53. package/utils/api.js +40 -35
  54. package/utils/auth.js +1 -0
package/bin/atris.js CHANGED
@@ -208,6 +208,13 @@ function showHelp() {
208
208
  console.log(' 2. Describe what you want (in your editor or terminal)');
209
209
  console.log(' 3. Agent shows visualization, you approve, it builds');
210
210
  console.log('');
211
+ console.log('Common invocations:');
212
+ console.log(' atris init');
213
+ console.log(' atris run');
214
+ console.log(' atris status');
215
+ console.log(' atris soul');
216
+ console.log(' atris fleet');
217
+ console.log('');
211
218
  console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
212
219
  console.log('');
213
220
  console.log('Setup:');
@@ -225,11 +232,16 @@ function showHelp() {
225
232
  console.log('Context & tracking:');
226
233
  console.log(' log - Add ideas to inbox');
227
234
  console.log(' activate - Load Atris context');
228
- console.log(' status - See active work and completions (--json for machine output)');
235
+ console.log(' status - See local work and completions (`atris status <business>` for remote)');
229
236
  console.log(' analytics - Show recent productivity from journals');
230
237
  console.log(' search - Search journal history (atris search <keyword>)');
231
238
  console.log(' clean - Housekeeping (stale tasks, archive journals, broken refs)');
232
239
  console.log(' verify - Validate work is done (tests, MAP.md, changes)');
240
+ console.log(' learn - Project learnings (patterns, pitfalls, preferences)');
241
+ console.log(' ingest - Local-first wiki ingest into atris/wiki/');
242
+ console.log(' query - Local-first wiki query against atris/wiki/');
243
+ console.log(' lint - Local-first wiki lint for atris/wiki/');
244
+ console.log(' loop - Local wiki upkeep loop (stale pages, orphans, next ingest)');
233
245
  console.log('');
234
246
  console.log('Optional helpers:');
235
247
  console.log(' brainstorm - Explore ideas conversationally before planning');
@@ -239,6 +251,7 @@ function showHelp() {
239
251
  console.log('Experiments:');
240
252
  console.log(' experiments init [slug] - Prepare atris/experiments/ or scaffold a pack');
241
253
  console.log(' experiments validate - Validate experiment packs');
254
+ console.log(' experiments run <slug> - Execute a pack or record an Endstate receipt');
242
255
  console.log(' experiments benchmark [m] - Run validate/runtime experiment benchmarks');
243
256
  console.log('');
244
257
  console.log('Quick commands:');
@@ -247,14 +260,31 @@ function showHelp() {
247
260
  console.log('');
248
261
  console.log('Sync:');
249
262
  console.log(' pull - Pull journals + member data from cloud');
263
+ console.log(' push - Push workspace files to cloud');
250
264
  console.log(' clean-workspace <slug> - Analyze & remove junk files from a workspace (alias: cw)');
251
265
  console.log('');
266
+ console.log('GitHub for Context:');
267
+ console.log(' browse [query] - Discover workspace templates');
268
+ console.log(' fork <template> - Clone a template into a new workspace');
269
+ console.log(' publish - Share your workspace as a template');
270
+ console.log(' sleep [business] - Pause workspace compute (context saved)');
271
+ console.log(' wake [business] - Resume workspace (agents restart)');
272
+ console.log('');
252
273
  console.log('Business:');
253
274
  console.log(' business add <slug> - Connect a business');
254
275
  console.log(' business list - Show connected businesses');
255
276
  console.log(' business remove <slug> - Disconnect a business');
277
+ console.log(' business team [slug] - Show members, roles, and admin access');
256
278
  console.log(' business health <slug> - Health report (members, workspace, issues)');
257
279
  console.log(' business audit - One-line health summary of all businesses');
280
+ console.log(' business create <name> - Create new business (cloud + local)');
281
+ console.log(' business connect <svc> - Wire a skill/integration');
282
+ console.log(' business notify <mode> - Set notification mode (digest/silent/push)');
283
+ console.log(' business deploy <slug> - Push local business to cloud');
284
+ console.log('');
285
+ console.log('Code Review:');
286
+ console.log(' code-review <file> - Run 6-specialist code review (alias: cr)');
287
+ console.log(' cr --all - Audit all backend services');
258
288
  console.log('');
259
289
  console.log('Cloud & agents:');
260
290
  console.log(' console - Start/attach always-on coding console (tmux daemon)');
@@ -293,6 +323,10 @@ function showHelp() {
293
323
  console.log(' plugin publish - Sync skills to marketplace repo and push');
294
324
  console.log(' plugin info - Preview what will be included');
295
325
  console.log('');
326
+ console.log('Feedback:');
327
+ console.log(' feedback "msg" - Submit feedback');
328
+ console.log(' feedback - List your feedback');
329
+ console.log('');
296
330
  console.log('Other:');
297
331
  console.log(' version - Show Atris version');
298
332
  console.log(' help - Show this help');
@@ -351,29 +385,25 @@ function showReviewHelp() {
351
385
 
352
386
  function showAutopilotHelp() {
353
387
  console.log('');
354
- console.log('Usage: atris autopilot "description" [options]');
355
- console.log(' atris autopilot --from-todo [options]');
388
+ console.log('Usage: atris autopilot [description] [options]');
356
389
  console.log('');
357
390
  console.log('Description:');
358
- console.log(' PRD-driven autonomous execution using claude -p.');
359
- console.log(' Runs plan do review cycles until acceptance criteria are met.');
391
+ console.log(' Suggests one task at a time with justification.');
392
+ console.log(' Human approves, skips, or cancels. Agent executes plan do review.');
393
+ console.log(' Detects work from: stale wiki pages, in-progress tasks, backlog, inbox.');
360
394
  console.log('');
361
395
  console.log('Options:');
362
- console.log(' --bug Treat as bug fix (different acceptance criteria)');
363
- console.log(' --from-todo Pick next item from TODO.md backlog');
364
- console.log(' --iterations=N Max iterations before stopping (default: 5)');
396
+ console.log(' --auto Execute without waiting for approval');
397
+ console.log(' --duration=TIME Run for a time limit (e.g. 1h, 30m, 90m)');
398
+ console.log(' --iterations=N Max tasks before stopping');
365
399
  console.log(' --verbose, -v Show detailed claude output');
366
- console.log(' --dry-run Generate PRD without executing');
400
+ console.log(' --dry-run Show suggestions without executing');
367
401
  console.log('');
368
402
  console.log('Examples:');
369
- console.log(' atris autopilot "Add dark mode toggle"');
370
- console.log(' atris autopilot --bug "Login fails on Safari"');
371
- console.log(' atris autopilot --from-todo --iterations=3');
372
- console.log('');
373
- console.log('Output:');
374
- console.log(' - prd.json: PRD with acceptance criteria');
375
- console.log(' - progress.txt: Execution log');
376
- console.log(' - Journal: Completion logged to today\'s journal');
403
+ console.log(' atris autopilot # Suggest from existing work');
404
+ console.log(' atris autopilot --auto --duration=1h # Autonomous for 1 hour');
405
+ console.log(' atris autopilot "Add dark mode toggle" # Seed inbox, then suggest');
406
+ console.log(' atris autopilot --auto --iterations=3 # Fully autonomous, 3 tasks max');
377
407
  console.log('');
378
408
  }
379
409
 
@@ -394,9 +424,11 @@ const { planAtris: planCmd, doAtris: doCmd, reviewAtris: reviewCmd } = require('
394
424
 
395
425
  // Check if this is a known command or natural language input
396
426
  const knownCommands = ['init', 'log', 'status', 'analytics', 'visualize', 'brainstorm', 'autopilot', 'run', 'plan', 'do', 'review',
397
- 'activate', 'agent', 'chat', 'console', 'login', 'logout', 'whoami', 'switch', 'use', 'accounts', '_resolve', '_profile-email', 'shell-init', 'update', 'upgrade', 'version', 'help', 'next', 'atris',
398
- 'clean', 'verify', 'search', 'skill', 'member', 'plugin', 'experiments', 'pull', 'push', 'business', 'sync',
399
- 'gmail', 'calendar', 'twitter', 'slack', 'integrations', 'setup', 'clean-workspace', 'cw'];
427
+ 'activate', '_activate', 'agent', 'chat', 'console', 'login', 'logout', 'whoami', 'switch', 'use', 'accounts', '_resolve', '_profile-email', '_switch-session', 'shell-init', 'update', 'upgrade', 'version', 'help', 'next', 'atris',
428
+ 'clean', 'verify', 'search', 'skill', 'member', 'learn', 'plugin', 'experiments', 'pull', 'push', 'align', 'terminal', 'diff', 'business', 'sync',
429
+ 'ingest', 'query', 'lint', 'loop',
430
+ 'gmail', 'calendar', 'twitter', 'slack', 'integrations', 'setup', 'clean-workspace', 'cw',
431
+ 'fork', 'browse', 'publish', 'sleep', 'wake', 'feedback', 'wiki', 'code-review', 'cr', 'soul', 'fleet'];
400
432
 
401
433
  // Check if command is an atris.md spec file - triggers welcome visualization
402
434
  function isSpecFile(cmd) {
@@ -409,7 +441,51 @@ if (isSpecFile(command)) {
409
441
  process.exit(0);
410
442
  }
411
443
 
444
+ // --version flag (works anywhere: atris --version, atris -v)
445
+ if (command === '--version' || command === '-v' || process.argv.includes('--version')) {
446
+ console.log(`atris v${CLI_VERSION}`);
447
+ process.exit(0);
448
+ }
449
+
412
450
  // If no command OR command is not recognized, treat as natural language
451
+ // Voice-friendly aliases — natural language → command mapping
452
+ // Solves speech-to-text issues (inspired by gstack v0.14.6 voice-triggers)
453
+ const voiceTriggers = {
454
+ 'review my code': 'code-review',
455
+ 'check my code': 'code-review',
456
+ 'run a review': 'code-review',
457
+ 'audit': 'code-review',
458
+ 'create a business': 'business',
459
+ 'start a business': 'business',
460
+ 'new business': 'business',
461
+ 'show status': 'status',
462
+ 'what happened': 'status',
463
+ 'whats going on': 'status',
464
+ 'run tests': 'verify',
465
+ 'check health': 'status',
466
+ 'deploy': 'business',
467
+ 'show my businesses': 'business',
468
+ 'pull latest': 'pull',
469
+ 'push changes': 'push',
470
+ 'show learnings': 'learn',
471
+ 'what did i learn': 'learn',
472
+ };
473
+
474
+ if (!command || !knownCommands.includes(command)) {
475
+ // Check voice triggers before falling through to natural language
476
+ const fullInput = process.argv.slice(2).join(' ').toLowerCase().trim();
477
+ const triggered = voiceTriggers[fullInput];
478
+ if (triggered) {
479
+ command = triggered;
480
+ // Re-check — if it's now a known command, fall through to dispatch
481
+ if (knownCommands.includes(command)) {
482
+ // Rewrite argv so dispatch works
483
+ process.argv[2] = command;
484
+ // Don't return — let it fall through to the command dispatch below
485
+ }
486
+ }
487
+ }
488
+
413
489
  if (!command || !knownCommands.includes(command)) {
414
490
  const userInput = process.argv.slice(2).join(' ');
415
491
 
@@ -730,6 +806,24 @@ if (command === 'init') {
730
806
  });
731
807
  } else if (command === 'console') {
732
808
  consoleCmd();
809
+ } else if (command === 'serve') {
810
+ // Start the local AI Computer bridge — make this directory addressable
811
+ // by cloud agents via the Atris API
812
+ const serveArgs = process.argv.slice(3);
813
+ const serveOptions = {};
814
+ for (let i = 0; i < serveArgs.length; i++) {
815
+ if (serveArgs[i] === '--agent' && serveArgs[i + 1]) {
816
+ serveOptions.agent = serveArgs[i + 1];
817
+ i++;
818
+ } else if (serveArgs[i] === '--allow-bash') {
819
+ serveOptions.allowBash = true;
820
+ }
821
+ }
822
+ require('../commands/serve').serveAtris(serveOptions)
823
+ .catch((err) => {
824
+ console.error(`✗ atris serve failed: ${err.message}`);
825
+ process.exit(1);
826
+ });
733
827
  } else if (command === 'version') {
734
828
  require('../commands/version').showVersion();
735
829
  } else if (command === 'login') {
@@ -750,6 +844,12 @@ if (command === 'init') {
750
844
  } else if (command === '_profile-email') {
751
845
  // Hidden: print email for a profile name
752
846
  require('../commands/auth').profileEmail();
847
+ } else if (command === '_activate') {
848
+ // Hidden: copy profile to credentials.json (global switch, legacy)
849
+ require('../commands/auth').activateGlobal();
850
+ } else if (command === '_switch-session') {
851
+ // Hidden: per-terminal switch — writes session file so each tab keeps its own account
852
+ require('../commands/auth').switchSession();
753
853
  } else if (command === 'shell-init') {
754
854
  require('../commands/auth').shellInit();
755
855
  } else if (command === 'visualize') {
@@ -801,35 +901,27 @@ if (command === 'init') {
801
901
  }
802
902
 
803
903
  // Parse options
804
- const isBug = args.includes('--bug');
805
- const fromTodo = args.includes('--from-todo');
806
904
  const verbose = args.includes('--verbose') || args.includes('-v');
807
905
  const dryRun = args.includes('--dry-run');
906
+ const auto = args.includes('--auto');
808
907
  const maxIterationsArg = args.find(a => a.startsWith('--iterations='));
809
- const maxIterations = maxIterationsArg ? parseInt(maxIterationsArg.split('=')[1]) : 5;
908
+ const maxIterations = maxIterationsArg ? parseInt(maxIterationsArg.split('=')[1]) : undefined;
909
+ const durationArg = args.find(a => a.startsWith('--duration='));
910
+ const duration = durationArg ? durationArg.split('=')[1] : null;
810
911
 
811
912
  // Get description (non-flag args)
812
- const description = args.filter(a => !a.startsWith('-')).join(' ').trim();
913
+ const description = args.filter(a => !a.startsWith('-')).join(' ').trim() || null;
813
914
 
814
915
  const options = {
815
- type: isBug ? 'bug' : 'feature',
816
- maxIterations,
916
+ ...(maxIterations !== undefined && { maxIterations }),
817
917
  verbose,
818
- dryRun
918
+ dryRun,
919
+ auto,
920
+ duration
819
921
  };
820
922
 
821
923
  let promise;
822
- if (fromTodo) {
823
- promise = require('../commands/autopilot').autopilotFromTodo(options);
824
- } else if (description) {
825
- promise = require('../commands/autopilot').autopilotAtris(description, options);
826
- } else {
827
- console.log('Usage: atris autopilot "description" [--bug] [--verbose] [--iterations=N]');
828
- console.log(' atris autopilot --from-todo');
829
- console.log('');
830
- console.log('Run `atris autopilot --help` for more options.');
831
- process.exit(1);
832
- }
924
+ promise = require('../commands/autopilot').autopilotAtris(description, options);
833
925
 
834
926
  promise
835
927
  .then(() => process.exit(0))
@@ -890,16 +982,16 @@ if (command === 'init') {
890
982
  process.exit(1);
891
983
  });
892
984
  } else if (command === 'status') {
893
- const subcommand = process.argv[3];
985
+ let subcommand = process.argv[3];
894
986
  if (subcommand && !subcommand.startsWith('-')) {
895
- // Business status: atris status <business-slug>
896
987
  require('../commands/context-sync').businessStatus(subcommand)
897
988
  .then(() => process.exit(0))
898
989
  .catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
899
990
  } else {
900
991
  const isQuick = process.argv.includes('--quick') || process.argv.includes('-q');
901
992
  const isJson = process.argv.includes('--json');
902
- statusCmd(isQuick, isJson);
993
+ const verbose = process.argv.includes('--verbose') || process.argv.includes('-v');
994
+ statusCmd(isQuick, isJson, verbose);
903
995
  }
904
996
  } else if (command === 'analytics') {
905
997
  require('../commands/analytics').analyticsAtris();
@@ -945,6 +1037,10 @@ if (command === 'init') {
945
1037
  integrationsStatus()
946
1038
  .then(() => process.exit(0))
947
1039
  .catch((err) => { console.error(`✗ Error: ${err.message || err}`); process.exit(1); });
1040
+ } else if (command === 'learn') {
1041
+ const subcommand = process.argv[3];
1042
+ const args = process.argv.slice(4);
1043
+ require('../commands/learn')(subcommand, ...args);
948
1044
  } else if (command === 'skill') {
949
1045
  const subcommand = process.argv[3];
950
1046
  const args = process.argv.slice(4);
@@ -961,12 +1057,61 @@ if (command === 'init') {
961
1057
  require('../commands/push').pushAtris()
962
1058
  .then(() => process.exit(0))
963
1059
  .catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
1060
+ } else if (command === 'align') {
1061
+ require('../commands/align').alignAtris()
1062
+ .then(() => process.exit(0))
1063
+ .catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
1064
+ } else if (command === 'terminal') {
1065
+ require('../commands/terminal').terminalAtris()
1066
+ .then(() => process.exit(0))
1067
+ .catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
1068
+ } else if (command === 'diff') {
1069
+ let diffSlug = process.argv[3];
1070
+ if (!diffSlug || diffSlug.startsWith('-')) {
1071
+ const bizFile = require('path').join(process.cwd(), '.atris', 'business.json');
1072
+ if (require('fs').existsSync(bizFile)) {
1073
+ try { diffSlug = JSON.parse(require('fs').readFileSync(bizFile, 'utf8')).slug; } catch {}
1074
+ }
1075
+ }
1076
+ if (!diffSlug) { console.error('Usage: atris diff [business] [path]'); process.exit(1); }
1077
+ require('../commands/context-sync').businessDiff(diffSlug)
1078
+ .then(() => process.exit(0))
1079
+ .catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
964
1080
  } else if (command === 'business') {
965
1081
  const subcommand = process.argv[3];
966
1082
  const args = process.argv.slice(4);
967
1083
  require('../commands/business').businessCommand(subcommand, ...args)
968
1084
  .then(() => process.exit(0))
969
1085
  .catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
1086
+ } else if (command === 'soul') {
1087
+ const args = process.argv.slice(3);
1088
+ require('../commands/soul').soul(args)
1089
+ .then(() => process.exit(0))
1090
+ .catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
1091
+ } else if (command === 'fleet') {
1092
+ const args = process.argv.slice(3);
1093
+ require('../commands/fleet').fleet(args)
1094
+ .then(() => process.exit(0))
1095
+ .catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
1096
+ } else if (command === 'code-review' || command === 'cr') {
1097
+ const args = process.argv.slice(3);
1098
+ require('../commands/review').reviewCommand(...args)
1099
+ } else if (command === 'wiki') {
1100
+ const subcommand = process.argv[3];
1101
+ const args = process.argv.slice(4);
1102
+ require('../commands/wiki').wikiCommand(subcommand, ...args)
1103
+ .then(() => process.exit(0))
1104
+ .catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
1105
+ } else if (command === 'ingest' || command === 'query' || command === 'lint') {
1106
+ const args = process.argv.slice(3);
1107
+ require('../commands/wiki').wikiCommand(command, ...args)
1108
+ .then(() => process.exit(0))
1109
+ .catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
1110
+ } else if (command === 'loop') {
1111
+ const args = process.argv.slice(3);
1112
+ require('../commands/loop').loopAtris(args)
1113
+ .then(() => process.exit(0))
1114
+ .catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
970
1115
  } else if (command === 'clean-workspace' || command === 'cw') {
971
1116
  const { cleanWorkspace } = require('../commands/workspace-clean');
972
1117
  cleanWorkspace()
@@ -984,6 +1129,30 @@ if (command === 'init') {
984
1129
  require('../commands/setup').setupAtris()
985
1130
  .then(() => process.exit(0))
986
1131
  .catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
1132
+ } else if (command === 'fork') {
1133
+ require('../commands/fork').forkAtris()
1134
+ .then(() => process.exit(0))
1135
+ .catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
1136
+ } else if (command === 'browse') {
1137
+ require('../commands/browse').browseAtris()
1138
+ .then(() => process.exit(0))
1139
+ .catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
1140
+ } else if (command === 'publish') {
1141
+ require('../commands/publish').publishAtris()
1142
+ .then(() => process.exit(0))
1143
+ .catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
1144
+ } else if (command === 'sleep') {
1145
+ require('../commands/lifecycle').sleepAtris()
1146
+ .then(() => process.exit(0))
1147
+ .catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
1148
+ } else if (command === 'wake') {
1149
+ require('../commands/lifecycle').wakeAtris()
1150
+ .then(() => process.exit(0))
1151
+ .catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
1152
+ } else if (command === 'feedback') {
1153
+ require('../commands/feedback').feedbackCommand()
1154
+ .then(() => process.exit(0))
1155
+ .catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
987
1156
  } else {
988
1157
  console.log(`Unknown command: ${command}`);
989
1158
  console.log('Run "atris help" to see available commands');
@@ -2,6 +2,7 @@ const fs = require('fs');
2
2
  const path = require('path');
3
3
  const { getLogPath, ensureLogDirectory, createLogFile } = require('../lib/journal');
4
4
  const { detectWorkspaceState, loadContext } = require('../lib/state-detection');
5
+ const { readWikiStatus } = require('../lib/wiki');
5
6
 
6
7
  function activateAtris() {
7
8
  const workspaceDir = process.cwd();
@@ -26,6 +27,7 @@ function activateAtris() {
26
27
 
27
28
  const state = detectWorkspaceState(workspaceDir);
28
29
  const context = loadContext(workspaceDir);
30
+ const wikiStatus = readWikiStatus(workspaceDir);
29
31
 
30
32
  // Check for handoff from previous session
31
33
  let handoffContent = null;
@@ -112,19 +114,43 @@ function activateAtris() {
112
114
  console.log('└─────────────────────────────────────────────────────────────┘');
113
115
  }
114
116
 
117
+ // Show learning count if learnings exist
118
+ let learningLine = '';
119
+ try {
120
+ const learningsPath = path.join(targetDir, 'learnings.jsonl');
121
+ if (fs.existsSync(learningsPath)) {
122
+ const lines = fs.readFileSync(learningsPath, 'utf8').trim().split('\n').filter(Boolean);
123
+ if (lines.length > 0) {
124
+ learningLine = ` • 🧠 ${lines.length} learnings`;
125
+ }
126
+ }
127
+ } catch {}
128
+
115
129
  console.log('');
116
- console.log(`📅 ${dateFormatted} • State: ${state.state}`);
130
+ console.log(`📅 ${dateFormatted} • State: ${state.state}${learningLine}`);
117
131
  console.log(` ${summaryLine}`);
132
+ if (wikiStatus) {
133
+ const healthLine = wikiStatus.bullets.find((line) => line.startsWith('- Health:'));
134
+ const wikiSummary = (healthLine || wikiStatus.bullets[0] || '- wiki scaffold ready').replace(/^- /, '');
135
+ console.log(` 🧠 Wiki: ${wikiSummary}`);
136
+ }
118
137
  console.log('');
119
138
  console.log('Core files:');
120
139
  console.log(`- ${fs.existsSync(personaFile) ? rel(personaFile) : 'atris/PERSONA.md (missing)'}`);
121
140
  console.log(`- ${fs.existsSync(mapFile) ? rel(mapFile) : 'atris/MAP.md (missing)'}`);
122
141
  console.log(`- ${taskFilePath ? rel(taskFilePath) : 'atris/TODO.md (missing)'}`);
123
142
  console.log(`- ${rel(logFile)}`);
143
+ if (wikiStatus?.statusPath) {
144
+ console.log(`- ${rel(wikiStatus.statusPath)}`);
145
+ }
146
+ if (wikiStatus?.bullets?.length) {
147
+ console.log('');
148
+ console.log('Wiki:');
149
+ wikiStatus.bullets.forEach((line) => console.log(`- ${line.replace(/^- /, '')}`));
150
+ }
124
151
  console.log('');
125
152
  console.log('Next: atris plan → do → review (or atris log)');
126
153
  console.log('');
127
154
  }
128
155
 
129
156
  module.exports = { activateAtris };
130
-