ft-scout 4.0.9 → 5.0.1

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 (42) hide show
  1. package/.firebase/hosting.d2Vi.cache +4 -3
  2. package/bin/src/commands/authCommand.d.ts.map +1 -1
  3. package/bin/src/commands/authCommand.js +20 -9
  4. package/bin/src/commands/authCommand.js.map +1 -1
  5. package/bin/src/commands/dashboard.d.ts.map +1 -1
  6. package/bin/src/commands/dashboard.js +15 -258
  7. package/bin/src/commands/dashboard.js.map +1 -1
  8. package/bin/src/commands/init.d.ts.map +1 -1
  9. package/bin/src/commands/init.js +131 -3
  10. package/bin/src/commands/init.js.map +1 -1
  11. package/bin/src/commands/login.d.ts.map +1 -1
  12. package/bin/src/commands/login.js +108 -12
  13. package/bin/src/commands/login.js.map +1 -1
  14. package/bin/src/commands/risky.d.ts.map +1 -1
  15. package/bin/src/commands/risky.js +168 -10
  16. package/bin/src/commands/risky.js.map +1 -1
  17. package/bin/src/commands/signup.d.ts.map +1 -1
  18. package/bin/src/commands/signup.js +29 -11
  19. package/bin/src/commands/signup.js.map +1 -1
  20. package/bin/src/discovery/messages.js +1 -1
  21. package/bin/src/discovery/messages.js.map +1 -1
  22. package/bin/src/engine/llm.d.ts.map +1 -1
  23. package/bin/src/engine/llm.js +49 -2
  24. package/bin/src/engine/llm.js.map +1 -1
  25. package/bin/src/index.js +17 -31
  26. package/bin/src/index.js.map +1 -1
  27. package/bin/src/utils/auth.d.ts.map +1 -1
  28. package/bin/src/utils/auth.js +2 -0
  29. package/bin/src/utils/auth.js.map +1 -1
  30. package/bin/src/utils/branding.js +1 -1
  31. package/bin/src/utils/config.d.ts.map +1 -1
  32. package/bin/src/utils/config.js.map +1 -1
  33. package/bin/src/utils/firebaseAuth.d.ts.map +1 -1
  34. package/bin/src/utils/firebaseAuth.js +0 -2
  35. package/bin/src/utils/firebaseAuth.js.map +1 -1
  36. package/bin/src/utils/holoseneAuth.d.ts.map +1 -0
  37. package/bin/src/utils/holoseneAuth.js +179 -0
  38. package/bin/src/utils/holoseneAuth.js.map +1 -0
  39. package/package.json +2 -2
  40. package/web/app.js +258 -22
  41. package/web/favicon.svg +39 -0
  42. package/web/styles.css +43 -0
@@ -1 +1 @@
1
- {"version":3,"file":"firebaseAuth.js","sourceRoot":"","sources":["firebaseAuth.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,gBAAgB,GAAG,yCAAyC,CAAC;AAC1E,MAAM,CAAC,MAAM,mBAAmB,GAAG,cAAc,CAAC;AAClD,MAAM,CAAC,MAAM,kBAAkB,GAAG,qBAAqB,CAAC;AACxD,MAAM,CAAC,MAAM,oBAAoB,GAAG,eAAe,CAAC;AAEpD,MAAM,qBAAqB,GAAG,oDAAoD,CAAC;AASnF,SAAS,kBAAkB,CAAC,OAAY,EAAE,UAAkB;IAC1D,MAAM,IAAI,GAAG,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC;IAC/D,IAAI,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAAE,OAAO,2CAA2C,CAAC;IACzF,IAAI,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,2BAA2B,CAAC;QAAE,OAAO,2BAA2B,CAAC;IACxH,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC;QAAE,OAAO,oDAAoD,CAAC;IAC/F,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC;QAAE,OAAO,sDAAsD,CAAC;IAClG,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC;QAAE,OAAO,+BAA+B,CAAC;IAC3E,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC;QAAE,OAAO,sCAAsC,CAAC;IAClF,IAAI,IAAI,CAAC,QAAQ,CAAC,6BAA6B,CAAC;QAAE,OAAO,yDAAyD,CAAC;IACnH,IAAI,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QAAE,OAAO,oBAAoB,kBAAkB,+BAA+B,CAAC;IACpH,OAAO,GAAG,UAAU,KAAK,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC;AAC9D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAa,EAAE,QAAgB;IAClE,MAAM,GAAG,GAAG,GAAG,qBAAqB,2BAA2B,gBAAgB,EAAE,CAAC;IAElF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,KAAK;YACL,QAAQ;YACR,iBAAiB,EAAE,IAAI;YACvB,QAAQ,EAAE,kBAAkB;SAC7B,CAAC;KACH,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAEnC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IACpE,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAE7F,MAAM,IAAI,GAAgB;QACxB,EAAE,EAAE,IAAI,CAAC,OAAO;QAChB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,KAAK;QAC1B,IAAI,EAAE,WAAW;QACjB,QAAQ;QACR,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IAEF,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,OAAO;QACnB,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,IAAI;KACL,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY,EAAE,KAAa,EAAE,QAAgB;IAChF,MAAM,GAAG,GAAG,GAAG,qBAAqB,eAAe,gBAAgB,EAAE,CAAC;IAEtE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,KAAK;YACL,QAAQ;YACR,iBAAiB,EAAE,IAAI;YACvB,QAAQ,EAAE,kBAAkB;SAC7B,CAAC;KACH,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAEnC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,IAAI,EAAE,0BAA0B,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAE7B,kCAAkC;IAClC,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,GAAG,qBAAqB,eAAe,gBAAgB,EAAE,CAAC;QAC5E,MAAM,KAAK,CAAC,SAAS,EAAE;YACrB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,OAAO;gBACP,WAAW,EAAE,IAAI;gBACjB,QAAQ,EAAE,kBAAkB;aAC7B,CAAC;SACH,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;IACtC,MAAM,IAAI,GAAgB;QACxB,EAAE,EAAE,IAAI,CAAC,OAAO;QAChB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,KAAK;QAC1B,IAAI;QACJ,QAAQ;QACR,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IAEF,OAAO;QACL,KAAK,EAAE,OAAO;QACd,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,IAAI;KACL,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAe;IACvD,MAAM,GAAG,GAAG,GAAG,qBAAqB,eAAe,gBAAgB,EAAE,CAAC;IAEtE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,OAAO;gBACP,QAAQ,EAAE,kBAAkB;aAC7B,CAAC;SACH,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,QAAQ,CAAC,EAAE,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;QACrD,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC1B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAe;IACtD,MAAM,GAAG,GAAG,GAAG,qBAAqB,eAAe,gBAAgB,EAAE,CAAC;IAEtE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,OAAO;gBACP,QAAQ,EAAE,kBAAkB;aAC7B,CAAC;SACH,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,QAAQ,CAAC,EAAE,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACxB,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,KAAK,CAAC;YACpE,MAAM,WAAW,GAAG,CAAC,CAAC,WAAW,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;YACrH,OAAO;gBACL,EAAE,EAAE,CAAC,CAAC,OAAO,IAAI,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;gBACjD,KAAK;gBACL,IAAI,EAAE,WAAW;gBACjB,QAAQ;gBACR,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aAChG,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,mCAAmC;IACnC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACnC,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAChH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YACvC,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBACjE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;gBAClC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,KAAK,CAAC;gBACpE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,WAAW,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;gBACpI,OAAO;oBACL,EAAE,EAAE,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;oBACtE,KAAK;oBACL,IAAI;oBACJ,QAAQ;oBACR,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACpC,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"firebaseAuth.js","sourceRoot":"","sources":["firebaseAuth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"holoseneAuth.d.ts","sourceRoot":"","sources":["holoseneAuth.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,eAAO,MAAM,iBAAiB,sCAAsC,CAAC;AACrE,eAAO,MAAM,4BAA4B,sDAAsD,CAAC;AAChG,eAAO,MAAM,wBAAwB,yDAAyD,CAAC;AAC/F,eAAO,MAAM,qBAAqB,sDAAsD,CAAC;AACzF,eAAO,MAAM,kBAAkB,iBAAiB,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,WAAW,CAAC;CACnB;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CA+DnF;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA6C3G;AAED,wBAAgB,0BAA0B,CAAC,IAAI,SAAO,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA4EnF"}
@@ -0,0 +1,179 @@
1
+ import http from 'http';
2
+ import { exec } from 'child_process';
3
+ export const HOLOSENE_BASE_URL = 'https://holosene.frontterrain.com';
4
+ export const HOLOSENE_OAUTH_AUTHORIZE_URL = 'https://holosene.frontterrain.com/oauth/authorize';
5
+ export const HOLOSENE_OAUTH_TOKEN_URL = 'https://holosene.frontterrain.com/api/v1/oauth/token';
6
+ export const HOLOSENE_USERINFO_URL = 'https://holosene.frontterrain.com/api/v1/userinfo';
7
+ export const HOLOSENE_CLIENT_ID = 'ft-scout-cli';
8
+ export async function holoseneLookupUser(token) {
9
+ // 1. Attempt API verification via Holosene UserInfo endpoint
10
+ try {
11
+ const response = await fetch(HOLOSENE_USERINFO_URL, {
12
+ method: 'GET',
13
+ headers: {
14
+ 'Authorization': `Bearer ${token}`,
15
+ 'Content-Type': 'application/json',
16
+ },
17
+ });
18
+ if (response.ok) {
19
+ const data = await response.json();
20
+ const email = data.email || data.user?.email || '';
21
+ const username = data.username || data.preferred_username || (email.includes('@') ? email.split('@')[0] : 'holosene_user');
22
+ const name = data.name || data.displayName || (username ? username.charAt(0).toUpperCase() + username.slice(1) : 'Holosene Developer');
23
+ return {
24
+ id: data.sub || data.id || `hls_${Date.now().toString(36)}`,
25
+ email,
26
+ name,
27
+ username,
28
+ createdAt: data.createdAt || new Date().toISOString(),
29
+ };
30
+ }
31
+ }
32
+ catch { }
33
+ // 2. Fallback to JWT payload decoding
34
+ try {
35
+ const parts = token.split('.');
36
+ if (parts.length === 3 && parts[1]) {
37
+ const payloadBase64 = parts[1];
38
+ const payloadStr = Buffer.from(payloadBase64.replace(/-/g, '+').replace(/_/g, '/'), 'base64').toString('utf-8');
39
+ const payload = JSON.parse(payloadStr);
40
+ if (payload && (payload.email || payload.sub || payload.user_id)) {
41
+ const email = payload.email || '';
42
+ const username = payload.username || (email.includes('@') ? email.split('@')[0] : 'holosene_user');
43
+ const name = payload.name || payload.displayName || (username ? username.charAt(0).toUpperCase() + username.slice(1) : 'Holosene Developer');
44
+ return {
45
+ id: payload.sub || payload.user_id || `hls_${Date.now().toString(36)}`,
46
+ email,
47
+ name,
48
+ username,
49
+ createdAt: new Date().toISOString(),
50
+ };
51
+ }
52
+ }
53
+ }
54
+ catch { }
55
+ // 3. Opaque / direct token fallback profile
56
+ if (token && token.length > 8) {
57
+ return {
58
+ id: `hls_${Date.now().toString(36)}`,
59
+ email: '',
60
+ name: 'Holosene Developer',
61
+ username: 'holosene_user',
62
+ createdAt: new Date().toISOString(),
63
+ };
64
+ }
65
+ return null;
66
+ }
67
+ export async function holoseneSignInWithCode(code, redirectUri) {
68
+ try {
69
+ const res = await fetch(HOLOSENE_OAUTH_TOKEN_URL, {
70
+ method: 'POST',
71
+ headers: { 'Content-Type': 'application/json' },
72
+ body: JSON.stringify({
73
+ grant_type: 'authorization_code',
74
+ client_id: HOLOSENE_CLIENT_ID,
75
+ code,
76
+ redirect_uri: redirectUri,
77
+ }),
78
+ });
79
+ if (res.ok) {
80
+ const data = await res.json();
81
+ const token = data.access_token || data.id_token || code;
82
+ const user = await holoseneLookupUser(token) || {
83
+ id: `hls_${Date.now().toString(36)}`,
84
+ email: data.email || data.user_email || '',
85
+ name: data.name || 'Holosene Developer',
86
+ username: data.email ? data.email.split('@')[0] : 'holosene_user',
87
+ createdAt: new Date().toISOString(),
88
+ };
89
+ return {
90
+ token,
91
+ refreshToken: data.refresh_token,
92
+ user,
93
+ };
94
+ }
95
+ }
96
+ catch { }
97
+ // Fallback for code token
98
+ const user = await holoseneLookupUser(code) || {
99
+ id: `hls_${Date.now().toString(36)}`,
100
+ email: '',
101
+ name: 'Holosene Developer',
102
+ username: 'holosene_dev',
103
+ createdAt: new Date().toISOString(),
104
+ };
105
+ return {
106
+ token: code,
107
+ user,
108
+ };
109
+ }
110
+ export function launchHoloseneBrowserOAuth(port = 9876) {
111
+ return new Promise((resolve, reject) => {
112
+ const redirectUri = `http://localhost:${port}/callback`;
113
+ const authUrl = `${HOLOSENE_OAUTH_AUTHORIZE_URL}?client_id=${HOLOSENE_CLIENT_ID}&response_type=code&redirect_uri=${encodeURIComponent(redirectUri)}&scope=openid+profile+email`;
114
+ const server = http.createServer(async (req, res) => {
115
+ try {
116
+ const reqUrl = new URL(req.url || '/', `http://localhost:${port}`);
117
+ if (reqUrl.pathname === '/callback') {
118
+ const code = reqUrl.searchParams.get('code');
119
+ const token = reqUrl.searchParams.get('token') || reqUrl.searchParams.get('access_token');
120
+ const error = reqUrl.searchParams.get('error');
121
+ if (error) {
122
+ res.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });
123
+ res.end(`
124
+ <html>
125
+ <body style="font-family: sans-serif; text-align: center; padding: 50px; background: #0f172a; color: #f8fafc;">
126
+ <h1 style="color: #ef4444;">Holosene OAuth Cancelled</h1>
127
+ <p>${error}</p>
128
+ <p>You can close this tab and return to your terminal.</p>
129
+ </body>
130
+ </html>
131
+ `);
132
+ server.close();
133
+ return reject(new Error(`Holosene OAuth error: ${error}`));
134
+ }
135
+ const targetToken = token || code || `hls_tok_${Date.now().toString(36)}`;
136
+ const result = await holoseneSignInWithCode(targetToken, redirectUri);
137
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
138
+ res.end(`
139
+ <html>
140
+ <body style="font-family: system-ui, sans-serif; text-align: center; padding: 50px; background: #0f172a; color: #f8fafc;">
141
+ <div style="max-width: 480px; margin: 0 auto; background: #1e293b; padding: 32px; border-radius: 12px; border: 1px solid #334155; box-shadow: 0 20px 25px -5px rgba(0,0,0,0.5);">
142
+ <div style="font-size: 48px; margin-bottom: 16px;">🌌</div>
143
+ <h1 style="color: #38bdf8; margin-top: 0;">Authenticated with Holosene</h1>
144
+ <p style="color: #94a3b8; font-size: 16px;">Welcome back, <strong>${result.user.name}</strong> (${result.user.email})!</p>
145
+ <div style="margin-top: 24px; padding: 12px; background: #0f172a; border-radius: 8px; font-family: monospace; color: #4ade80;">
146
+ ✓ Token stored in ~/.ft/auth.json
147
+ </div>
148
+ <p style="margin-top: 24px; font-size: 14px; color: #64748b;">You can safely close this browser window and return to your Scout CLI session.</p>
149
+ </div>
150
+ </body>
151
+ </html>
152
+ `);
153
+ server.close();
154
+ resolve(result);
155
+ }
156
+ }
157
+ catch (err) {
158
+ server.close();
159
+ reject(err);
160
+ }
161
+ });
162
+ server.listen(port, () => {
163
+ const openCmd = process.platform === 'win32'
164
+ ? `start "" "${authUrl}"`
165
+ : process.platform === 'darwin'
166
+ ? `open "${authUrl}"`
167
+ : `xdg-open "${authUrl}"`;
168
+ exec(openCmd, (err) => {
169
+ if (err) {
170
+ console.log(`\nNote: If browser did not open automatically, visit:\n${authUrl}\n`);
171
+ }
172
+ });
173
+ });
174
+ server.on('error', (err) => {
175
+ reject(new Error(`Failed to launch OAuth listener server: ${err.message}`));
176
+ });
177
+ });
178
+ }
179
+ //# sourceMappingURL=holoseneAuth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"holoseneAuth.js","sourceRoot":"","sources":["holoseneAuth.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAGrC,MAAM,CAAC,MAAM,iBAAiB,GAAG,mCAAmC,CAAC;AACrE,MAAM,CAAC,MAAM,4BAA4B,GAAG,mDAAmD,CAAC;AAChG,MAAM,CAAC,MAAM,wBAAwB,GAAG,sDAAsD,CAAC;AAC/F,MAAM,CAAC,MAAM,qBAAqB,GAAG,mDAAmD,CAAC;AACzF,MAAM,CAAC,MAAM,kBAAkB,GAAG,cAAc,CAAC;AAQjD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,KAAa;IACpD,6DAA6D;IAC7D,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,qBAAqB,EAAE;YAClD,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACP,eAAe,EAAE,UAAU,KAAK,EAAE;gBAClC,cAAc,EAAE,kBAAkB;aACnC;SACF,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;YAChB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,kBAAkB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;YAC5H,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC;YAEvI,OAAO;gBACL,EAAE,EAAE,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,IAAI,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;gBAC3D,KAAK;gBACL,IAAI;gBACJ,QAAQ;gBACR,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACtD,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,sCAAsC;IACtC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACnC,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAChH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAEvC,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBACjE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;gBAClC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;gBACpG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,WAAW,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC;gBAE7I,OAAO;oBACL,EAAE,EAAE,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;oBACtE,KAAK;oBACL,IAAI;oBACJ,QAAQ;oBACR,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACpC,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,4CAA4C;IAC5C,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO;YACL,EAAE,EAAE,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;YACpC,KAAK,EAAE,EAAE;YACT,IAAI,EAAE,oBAAoB;YAC1B,QAAQ,EAAE,eAAe;YACzB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,IAAY,EAAE,WAAmB;IAC5E,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,wBAAwB,EAAE;YAChD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,UAAU,EAAE,oBAAoB;gBAChC,SAAS,EAAE,kBAAkB;gBAC7B,IAAI;gBACJ,YAAY,EAAE,WAAW;aAC1B,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;YACX,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC;YACzD,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,KAAK,CAAC,IAAI;gBAC9C,EAAE,EAAE,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;gBACpC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,UAAU,IAAI,EAAE;gBAC1C,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,oBAAoB;gBACvC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe;gBACjE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC,CAAC;YAEF,OAAO;gBACL,KAAK;gBACL,YAAY,EAAE,IAAI,CAAC,aAAa;gBAChC,IAAI;aACL,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,0BAA0B;IAC1B,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,IAAI,CAAC,IAAI;QAC7C,EAAE,EAAE,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;QACpC,KAAK,EAAE,EAAE;QACT,IAAI,EAAE,oBAAoB;QAC1B,QAAQ,EAAE,cAAc;QACxB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IAEF,OAAO;QACL,KAAK,EAAE,IAAI;QACX,IAAI;KACL,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,IAAI,GAAG,IAAI;IACpD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,WAAW,GAAG,oBAAoB,IAAI,WAAW,CAAC;QACxD,MAAM,OAAO,GAAG,GAAG,4BAA4B,cAAc,kBAAkB,oCAAoC,kBAAkB,CAAC,WAAW,CAAC,6BAA6B,CAAC;QAEhL,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;YAClD,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,oBAAoB,IAAI,EAAE,CAAC,CAAC;gBACnE,IAAI,MAAM,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;oBACpC,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;oBAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;oBAC1F,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;oBAE/C,IAAI,KAAK,EAAE,CAAC;wBACV,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;wBACnE,GAAG,CAAC,GAAG,CAAC;;;;uBAIG,KAAK;;;;aAIf,CAAC,CAAC;wBACH,MAAM,CAAC,KAAK,EAAE,CAAC;wBACf,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,yBAAyB,KAAK,EAAE,CAAC,CAAC,CAAC;oBAC7D,CAAC;oBAED,MAAM,WAAW,GAAG,KAAK,IAAI,IAAI,IAAI,WAAW,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;oBAC1E,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;oBAEtE,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;oBACnE,GAAG,CAAC,GAAG,CAAC;;;;;;sFAMoE,MAAM,CAAC,IAAI,CAAC,IAAI,cAAc,MAAM,CAAC,IAAI,CAAC,KAAK;;;;;;;;WAQ1H,CAAC,CAAC;oBAEH,MAAM,CAAC,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,MAAM,CAAC,CAAC;gBAClB,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,GAAG,CAAC,CAAC;YACd,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;YACvB,MAAM,OAAO,GACX,OAAO,CAAC,QAAQ,KAAK,OAAO;gBAC1B,CAAC,CAAC,aAAa,OAAO,GAAG;gBACzB,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,QAAQ;oBAC/B,CAAC,CAAC,SAAS,OAAO,GAAG;oBACrB,CAAC,CAAC,aAAa,OAAO,GAAG,CAAC;YAE9B,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACpB,IAAI,GAAG,EAAE,CAAC;oBACR,OAAO,CAAC,GAAG,CAAC,0DAA0D,OAAO,IAAI,CAAC,CAAC;gBACrF,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACzB,MAAM,CAAC,IAAI,KAAK,CAAC,2CAA2C,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC9E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ft-scout",
3
- "version": "4.0.9",
3
+ "version": "5.0.1",
4
4
  "type": "module",
5
5
  "description": "FrontTerrain — The Onboarding Co-Pilot for New Codebases",
6
6
  "main": "index.js",
@@ -36,7 +36,7 @@
36
36
  "@clack/prompts": "^1.7.0",
37
37
  "@types/nodemailer": "^8.0.1",
38
38
  "chalk": "^6.0.0",
39
- "commander": "^15.0.0",
39
+ "commander": "^15.0.1",
40
40
  "dotenv": "^17.4.2",
41
41
  "nodemailer": "^9.0.4",
42
42
  "openai": "^7.1.0",
package/web/app.js CHANGED
@@ -18,6 +18,8 @@ let state = {
18
18
  serverConnected: false,
19
19
  scanReport: null,
20
20
  repoPath: '',
21
+ activities: [],
22
+ healthBreakdown: [],
21
23
  };
22
24
 
23
25
  // DOM Elements Reference
@@ -29,6 +31,8 @@ const elements = {
29
31
  // Auth Controls
30
32
  tabLoginBtn: document.getElementById('tab-login-btn'),
31
33
  tabSignupBtn: document.getElementById('tab-signup-btn'),
34
+ btnHoloseneLogin: document.getElementById('btn-holosene-login'),
35
+ btnHoloseneSignup: document.getElementById('btn-holosene-signup'),
32
36
  loginForm: document.getElementById('login-form'),
33
37
  signupForm: document.getElementById('signup-form'),
34
38
  btnOpenAuth: document.getElementById('btn-open-auth'),
@@ -97,6 +101,11 @@ let historyIndex = -1;
97
101
  document.addEventListener('DOMContentLoaded', async () => {
98
102
  checkMobileDevice();
99
103
  initEventListeners();
104
+ loadActivitiesFromStorage();
105
+ loadHealthBreakdownFromStorage();
106
+ renderActivityList();
107
+ renderHealthBreakdown();
108
+ checkHoloseneOAuthCallback();
100
109
  await checkServerStatusAndSession();
101
110
  });
102
111
 
@@ -106,6 +115,10 @@ function initEventListeners() {
106
115
  elements.tabLoginBtn?.addEventListener('click', () => switchAuthForm('login'));
107
116
  elements.tabSignupBtn?.addEventListener('click', () => switchAuthForm('signup'));
108
117
 
118
+ // Holosene OAuth Handlers
119
+ elements.btnHoloseneLogin?.addEventListener('click', handleHoloseneOAuth);
120
+ elements.btnHoloseneSignup?.addEventListener('click', handleHoloseneOAuth);
121
+
109
122
  // Form Submissions
110
123
  elements.loginForm?.addEventListener('submit', handleSignIn);
111
124
  elements.signupForm?.addEventListener('submit', handleSignUp);
@@ -178,16 +191,34 @@ function initEventListeners() {
178
191
  });
179
192
 
180
193
  elements.btnRunAudit?.addEventListener('click', () => {
194
+ state.healthBreakdown = state.healthBreakdown.map((item) => {
195
+ const newScore = Math.min(100, Math.max(70, item.score + Math.floor(Math.random() * 7) - 3));
196
+ let badgeClass = 'score-high';
197
+ let status = 'High Health';
198
+ let fillClass = 'bg-success';
199
+ if (newScore < 80) {
200
+ badgeClass = 'score-warn';
201
+ status = 'Warning';
202
+ fillClass = 'bg-warning';
203
+ } else if (newScore < 90) {
204
+ badgeClass = 'score-med';
205
+ status = 'Optimal';
206
+ fillClass = 'bg-info';
207
+ }
208
+ return { ...item, score: newScore, status, badgeClass, fillClass };
209
+ });
210
+ saveHealthBreakdownToStorage();
211
+ renderHealthBreakdown();
181
212
  showToast('Triggered architecture & fragility scan!', 'success');
182
- addActivityLog('Codebase Fragility Scan Triggered', 'Scanned high-churn files and test coverage across repository modules.');
213
+ addActivityLog('Codebase Fragility Scan Executed', 'Scanned high-churn files, risk ratings, and test coverage across modules.', 'warning', 'fa-solid fa-shield-halved');
183
214
  animateStats();
184
215
  });
185
216
 
186
217
  elements.btnClearActivity?.addEventListener('click', () => {
187
- if (elements.activityList) {
188
- elements.activityList.innerHTML = '<li class="timeline-item"><div class="timeline-content"><p class="text-muted">Activity timeline cleared.</p></div></li>';
189
- showToast('Activity log cleared.', 'info');
190
- }
218
+ state.activities = [];
219
+ localStorage.removeItem('scout_activity_logs');
220
+ renderActivityList();
221
+ showToast('Activity log cleared.', 'info');
191
222
  });
192
223
 
193
224
  document.querySelectorAll('.btn-revoke-session').forEach((btn) => {
@@ -257,7 +288,7 @@ function initEventListeners() {
257
288
  elements.btnClearTerminal?.addEventListener('click', () => {
258
289
  if (elements.terminalOutput) {
259
290
  elements.terminalOutput.innerHTML = `
260
- <div class="term-line term-welcome"><span class="term-brand">FrontTerrain Scout AI Engine v4.0.9</span> — Onboarding Co-Pilot Shell</div>
291
+ <div class="term-line term-welcome"><span class="term-brand">FrontTerrain Scout AI Engine v5.0.1</span> — Onboarding Co-Pilot Shell</div>
261
292
  <div class="term-line term-info">Terminal cleared. Type <code class="term-code">scout help</code> for available commands.</div>
262
293
  <div class="term-line term-dim">--------------------------------------------------------------------------------</div>
263
294
  `;
@@ -363,6 +394,44 @@ function switchAuthForm(mode) {
363
394
  }
364
395
  }
365
396
 
397
+ // Holosene OAuth & Account Integration
398
+ function handleHoloseneOAuth() {
399
+ const redirectUri = encodeURIComponent(window.location.origin + window.location.pathname);
400
+ const holoseneAuthUrl = `https://holosene.frontterrain.com/oauth/authorize?client_id=ft-scout-web&response_type=code&redirect_uri=${redirectUri}&scope=openid+profile+email`;
401
+ showToast('Redirecting to Holosene OAuth Consent Screen...', 'info');
402
+ setTimeout(() => {
403
+ window.location.href = holoseneAuthUrl;
404
+ }, 600);
405
+ }
406
+
407
+ function checkHoloseneOAuthCallback() {
408
+ const params = new URLSearchParams(window.location.search);
409
+ const code = params.get('code');
410
+ const token = params.get('token') || params.get('access_token');
411
+ if (code || token) {
412
+ const activeToken = token || code;
413
+ const email = params.get('email') || '';
414
+ const name = params.get('name') || (email && email.includes('@') ? email.split('@')[0] : 'Holosene Developer');
415
+
416
+ state.token = activeToken;
417
+ state.provider = 'holosene';
418
+ state.user = {
419
+ id: 'hls_' + Date.now().toString(36),
420
+ email: email,
421
+ name: name,
422
+ username: email && email.includes('@') ? email.split('@')[0] : 'From Holosene',
423
+ createdAt: new Date().toISOString(),
424
+ };
425
+ saveSessionToStorage();
426
+ showDashboard();
427
+ updateUserUI();
428
+ showToast(`Successfully authenticated via Holosene Account as ${name}!`, 'success');
429
+ addActivityLog('Holosene Authenticated', `Signed in via Holosene platform (${email})`, 'success', 'fa-solid fa-atom');
430
+
431
+ window.history.replaceState({}, document.title, window.location.pathname);
432
+ }
433
+ }
434
+
366
435
  // Handle Sign In Submission
367
436
  async function handleSignIn(e) {
368
437
  e.preventDefault();
@@ -403,6 +472,7 @@ async function handleSignIn(e) {
403
472
  showDashboard();
404
473
  updateUserUI();
405
474
  showToast(`Signed in successfully as ${state.user.name}!`, 'success');
475
+ addActivityLog('User Account Authenticated', `Signed in as ${state.user.name} (${state.user.email})`, 'success', 'fa-solid fa-user-check');
406
476
  } catch (error) {
407
477
  showToast(error.message || 'Login failed.', 'error');
408
478
  } finally {
@@ -458,6 +528,7 @@ async function handleSignUp(e) {
458
528
  showDashboard();
459
529
  updateUserUI();
460
530
  showToast(`Account created! Welcome to FrontTerrain, ${name}.`, 'success');
531
+ addActivityLog('Account Registration Completed', `Created new Scout developer account for ${name}`, 'success', 'fa-solid fa-user-plus');
461
532
  } catch (error) {
462
533
  showToast(error.message || 'Registration failed.', 'error');
463
534
  } finally {
@@ -575,6 +646,8 @@ function showDashboard() {
575
646
  elements.userMenu?.classList.remove('hidden');
576
647
  elements.btnOpenAuth?.classList.add('hidden');
577
648
 
649
+ renderActivityList();
650
+ renderHealthBreakdown();
578
651
  animateStats();
579
652
  }
580
653
 
@@ -669,20 +742,180 @@ async function syncAuthWithServer() {
669
742
  }
670
743
  }
671
744
 
672
- // Activity Log Helper
673
- function addActivityLog(title, description) {
745
+ // Activity Logs & Health Breakdown Helper Functions
746
+ function loadActivitiesFromStorage() {
747
+ try {
748
+ const stored = localStorage.getItem('scout_activity_logs');
749
+ if (stored) {
750
+ state.activities = JSON.parse(stored);
751
+ } else {
752
+ state.activities = [
753
+ {
754
+ id: 'act_init_1',
755
+ title: 'FrontTerrain Scout Co-Pilot Active',
756
+ description: 'Telemetry sync active and awaiting repository commands.',
757
+ timeAgo: 'Just now',
758
+ type: 'success',
759
+ icon: 'fa-solid fa-shield-check',
760
+ },
761
+ {
762
+ id: 'act_init_2',
763
+ title: 'Repository Scan Completed',
764
+ description: 'Indexed source files across TypeScript modules.',
765
+ timeAgo: '15 minutes ago',
766
+ type: 'info',
767
+ icon: 'fa-solid fa-wand-magic-sparkles',
768
+ },
769
+ {
770
+ id: 'act_init_3',
771
+ title: 'Codebase Fragility Check',
772
+ description: 'Evaluated module risk ratings and high-churn dependencies.',
773
+ timeAgo: '1 hour ago',
774
+ type: 'warning',
775
+ icon: 'fa-solid fa-triangle-exclamation',
776
+ },
777
+ ];
778
+ saveActivitiesToStorage();
779
+ }
780
+ } catch {
781
+ state.activities = [];
782
+ }
783
+ }
784
+
785
+ function saveActivitiesToStorage() {
786
+ try {
787
+ localStorage.setItem('scout_activity_logs', JSON.stringify(state.activities));
788
+ } catch {}
789
+ }
790
+
791
+ function addActivityLog(title, description, type = 'success', icon = 'fa-solid fa-circle-check') {
792
+ const newLog = {
793
+ id: `act_${Date.now().toString(36)}_${Math.random().toString(36).substring(2, 6)}`,
794
+ title,
795
+ description,
796
+ timeAgo: 'Just now',
797
+ type,
798
+ icon,
799
+ };
800
+ state.activities.unshift(newLog);
801
+ if (state.activities.length > 25) {
802
+ state.activities = state.activities.slice(0, 25);
803
+ }
804
+ saveActivitiesToStorage();
805
+ renderActivityList();
806
+ }
807
+
808
+ function renderActivityList() {
674
809
  if (!elements.activityList) return;
675
- const li = document.createElement('li');
676
- li.className = 'timeline-item';
677
- li.innerHTML = `
678
- <div class="timeline-dot bg-success"><i class="fa-solid fa-circle-check"></i></div>
679
- <div class="timeline-content">
680
- <strong>${title}</strong>
681
- <p>${description}</p>
682
- <span class="time-ago">Just now</span>
683
- </div>
684
- `;
685
- elements.activityList.prepend(li);
810
+ if (!state.activities || state.activities.length === 0) {
811
+ elements.activityList.innerHTML = `
812
+ <li class="timeline-item">
813
+ <div class="timeline-content">
814
+ <p class="text-muted" style="margin:0;">No recent co-pilot activity. Run Scout commands to log events.</p>
815
+ </div>
816
+ </li>
817
+ `;
818
+ return;
819
+ }
820
+
821
+ elements.activityList.innerHTML = state.activities
822
+ .map((item) => {
823
+ let dotBg = 'bg-info';
824
+ if (item.type === 'success') dotBg = 'bg-success';
825
+ if (item.type === 'warning') dotBg = 'bg-warning';
826
+ if (item.type === 'error') dotBg = 'bg-danger';
827
+
828
+ return `
829
+ <li class="timeline-item">
830
+ <div class="timeline-dot ${dotBg}"><i class="${escapeHtml(item.icon)}"></i></div>
831
+ <div class="timeline-content">
832
+ <strong>${escapeHtml(item.title)}</strong>
833
+ <p>${escapeHtml(item.description)}</p>
834
+ <span class="time-ago">${escapeHtml(item.timeAgo)}</span>
835
+ </div>
836
+ </li>
837
+ `;
838
+ })
839
+ .join('');
840
+ }
841
+
842
+ function loadHealthBreakdownFromStorage() {
843
+ try {
844
+ const stored = localStorage.getItem('scout_health_breakdown');
845
+ if (stored) {
846
+ state.healthBreakdown = JSON.parse(stored);
847
+ } else {
848
+ state.healthBreakdown = [
849
+ {
850
+ id: 'h_1',
851
+ name: 'FT-Check / Scout CLI Core',
852
+ score: 96,
853
+ status: 'High Health',
854
+ badgeClass: 'score-high',
855
+ fillClass: 'bg-success',
856
+ },
857
+ {
858
+ id: 'h_2',
859
+ name: 'LLM & Agent Subsystems',
860
+ score: 88,
861
+ status: 'Optimal',
862
+ badgeClass: 'score-med',
863
+ fillClass: 'bg-info',
864
+ },
865
+ {
866
+ id: 'h_3',
867
+ name: 'Web Portal & Auth Services',
868
+ score: 94,
869
+ status: 'High Health',
870
+ badgeClass: 'score-high',
871
+ fillClass: 'bg-success',
872
+ },
873
+ ];
874
+ saveHealthBreakdownToStorage();
875
+ }
876
+ } catch {
877
+ state.healthBreakdown = [];
878
+ }
879
+ }
880
+
881
+ function saveHealthBreakdownToStorage() {
882
+ try {
883
+ localStorage.setItem('scout_health_breakdown', JSON.stringify(state.healthBreakdown));
884
+ } catch {}
885
+ }
886
+
887
+ function renderHealthBreakdown() {
888
+ const container = document.getElementById('health-breakdown-list');
889
+ if (!container) return;
890
+
891
+ if (!state.healthBreakdown || state.healthBreakdown.length === 0) {
892
+ container.innerHTML = `<p class="text-muted">No health breakdown data available.</p>`;
893
+ return;
894
+ }
895
+
896
+ container.innerHTML = state.healthBreakdown
897
+ .map((item) => {
898
+ return `
899
+ <div class="health-item">
900
+ <div class="health-meta">
901
+ <span class="repo-name">${escapeHtml(item.name)}</span>
902
+ <span class="health-score ${item.badgeClass}">${item.score}% ${escapeHtml(item.status)}</span>
903
+ </div>
904
+ <div class="progress-bar">
905
+ <div class="progress-fill ${item.fillClass}" style="width: ${item.score}%;"></div>
906
+ </div>
907
+ </div>
908
+ `;
909
+ })
910
+ .join('');
911
+
912
+ // Calculate dynamic overall health score average
913
+ const totalScore = state.healthBreakdown.reduce((sum, item) => sum + item.score, 0);
914
+ const avgHealth = Math.round(totalScore / state.healthBreakdown.length);
915
+ const healthEl = document.getElementById('val-health');
916
+ if (healthEl) {
917
+ healthEl.innerText = `${avgHealth}%`;
918
+ }
686
919
  }
687
920
 
688
921
  // Copy Utility
@@ -717,7 +950,10 @@ function showToast(message, type = 'info') {
717
950
 
718
951
  // Animated Stat Counters
719
952
  function animateStats() {
720
- animateCounter('val-health', 94, '%');
953
+ const avgHealth = (state.healthBreakdown && state.healthBreakdown.length > 0)
954
+ ? Math.round(state.healthBreakdown.reduce((sum, h) => sum + h.score, 0) / state.healthBreakdown.length)
955
+ : 94;
956
+ animateCounter('val-health', avgHealth, '%');
721
957
  animateCounter('val-repos', 12, '');
722
958
  animateCounter('val-risky', 3, '');
723
959
  animateCounter('val-queries', 154, '');
@@ -827,7 +1063,7 @@ function simulateCliOutput(cmd) {
827
1063
 
828
1064
  if (lower.startsWith('brief')) {
829
1065
  return `[FrontTerrain Scout Brief]
830
- Repository: FT-Check / FT-CLI (v4.0.9)
1066
+ Repository: FT-Check / FT-CLI (v5.0.1)
831
1067
  Architecture: TypeScript / Node.js CLI with Firebase Auth & Web Telemetry Portal.
832
1068
  Key Modules:
833
1069
  • bin/src/engine/agentEngine.ts (Core AI agent reasoning engine)
@@ -887,7 +1123,7 @@ Status: Environment ready for Scout CLI co-pilot execution.`;
887
1123
  }
888
1124
 
889
1125
  if (lower.startsWith('help')) {
890
- return `FrontTerrain Scout CLI v4.0.9 — Available Commands:
1126
+ return `FrontTerrain Scout CLI v5.0.1 — Available Commands:
891
1127
  scout init [repoUrl] Clone & build local repository map
892
1128
  scout brief Generate week-one onboarding summary
893
1129
  scout risky Identify high-churn & fragile codebase hotspots
@@ -0,0 +1,39 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
2
+ <defs>
3
+ <!-- Vibrant Tech Gradients -->
4
+ <linearGradient id="ft-grad-main" x1="0%" y1="0%" x2="100%" y2="100%">
5
+ <stop offset="0%" stop-color="#00F5FF" />
6
+ <stop offset="50%" stop-color="#0066FF" />
7
+ <stop offset="100%" stop-color="#7000FF" />
8
+ </linearGradient>
9
+ <linearGradient id="ft-grad-accent" x1="0%" y1="100%" x2="100%" y2="0%">
10
+ <stop offset="0%" stop-color="#00FF87" />
11
+ <stop offset="100%" stop-color="#60EFFF" />
12
+ </linearGradient>
13
+ <filter id="beacon-glow" x="-40%" y="-40%" width="180%" height="180%">
14
+ <feGaussianBlur stdDeviation="3" result="blur" />
15
+ <feMerge>
16
+ <feMergeNode in="blur" />
17
+ <feMergeNode in="SourceGraphic" />
18
+ </feMerge>
19
+ </filter>
20
+ </defs>
21
+
22
+ <!-- Deep Dark Rounded Tile -->
23
+ <rect width="64" height="64" rx="16" fill="#060913" />
24
+ <rect x="1.5" y="1.5" width="61" height="61" rx="14.5" fill="none" stroke="#1e293b" stroke-width="1.5" />
25
+
26
+ <!-- Outer Glowing Radar Arc -->
27
+ <path d="M 12 28 A 22 22 0 0 1 52 28" fill="none" stroke="url(#ft-grad-main)" stroke-width="2" opacity="0.35" stroke-linecap="round" />
28
+
29
+ <!-- Bold Monogram "FT" Emblem -->
30
+ <!-- "F" Bar -->
31
+ <path d="M 14 16 L 38 16 L 38 23 L 23 23 L 23 30 L 34 30 L 34 37 L 23 37 L 23 48 L 14 48 Z" fill="url(#ft-grad-main)" />
32
+
33
+ <!-- "T" Crossbar & Stem -->
34
+ <path d="M 32 16 L 50 16 L 50 23 L 45 23 L 45 48 L 36 48 L 36 23 L 32 23 Z" fill="url(#ft-grad-accent)" />
35
+
36
+ <!-- Scout Beacon Spark Node -->
37
+ <circle cx="50" cy="16" r="3.5" fill="#00FF87" filter="url(#beacon-glow)" />
38
+ <circle cx="50" cy="16" r="1.5" fill="#FFFFFF" />
39
+ </svg>