openanima 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/index.js +335 -126
- package/package.json +3 -3
package/dist/bin/index.js
CHANGED
|
@@ -11,9 +11,16 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
11
11
|
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
12
12
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
13
13
|
});
|
|
14
|
+
var __esm = (fn, res) => function __init() {
|
|
15
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
16
|
+
};
|
|
14
17
|
var __commonJS = (cb, mod) => function __require2() {
|
|
15
18
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
16
19
|
};
|
|
20
|
+
var __export = (target, all) => {
|
|
21
|
+
for (var name in all)
|
|
22
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
23
|
+
};
|
|
17
24
|
var __copyProps = (to, from, except, desc) => {
|
|
18
25
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
19
26
|
for (let key of __getOwnPropNames(from))
|
|
@@ -6618,16 +6625,152 @@ var require_crypto_js = __commonJS({
|
|
|
6618
6625
|
}
|
|
6619
6626
|
});
|
|
6620
6627
|
|
|
6628
|
+
// src/lib/config.ts
|
|
6629
|
+
var config_exports = {};
|
|
6630
|
+
__export(config_exports, {
|
|
6631
|
+
getConfigPath: () => getConfigPath,
|
|
6632
|
+
readConfig: () => readConfig,
|
|
6633
|
+
writeConfig: () => writeConfig
|
|
6634
|
+
});
|
|
6635
|
+
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
6636
|
+
import { homedir } from "os";
|
|
6637
|
+
import { join } from "path";
|
|
6638
|
+
async function readConfig() {
|
|
6639
|
+
try {
|
|
6640
|
+
const raw = await readFile(CONFIG_FILE, "utf-8");
|
|
6641
|
+
return JSON.parse(raw);
|
|
6642
|
+
} catch {
|
|
6643
|
+
return {};
|
|
6644
|
+
}
|
|
6645
|
+
}
|
|
6646
|
+
async function writeConfig(config) {
|
|
6647
|
+
await mkdir(CONFIG_DIR, { recursive: true });
|
|
6648
|
+
const existing = await readConfig();
|
|
6649
|
+
const merged = { ...existing, ...config };
|
|
6650
|
+
await writeFile(CONFIG_FILE, JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
6651
|
+
}
|
|
6652
|
+
function getConfigPath() {
|
|
6653
|
+
return CONFIG_FILE;
|
|
6654
|
+
}
|
|
6655
|
+
var CONFIG_DIR, CONFIG_FILE;
|
|
6656
|
+
var init_config = __esm({
|
|
6657
|
+
"src/lib/config.ts"() {
|
|
6658
|
+
"use strict";
|
|
6659
|
+
CONFIG_DIR = join(homedir(), ".openanima");
|
|
6660
|
+
CONFIG_FILE = join(CONFIG_DIR, "config.json");
|
|
6661
|
+
}
|
|
6662
|
+
});
|
|
6663
|
+
|
|
6664
|
+
// src/lib/api-client.ts
|
|
6665
|
+
var api_client_exports = {};
|
|
6666
|
+
__export(api_client_exports, {
|
|
6667
|
+
createApiClient: () => createApiClient
|
|
6668
|
+
});
|
|
6669
|
+
function createApiClient(config = {}) {
|
|
6670
|
+
const baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;
|
|
6671
|
+
const apiKey = config.apiKey;
|
|
6672
|
+
let token = config.token;
|
|
6673
|
+
async function request(method, path, body) {
|
|
6674
|
+
const headers = {
|
|
6675
|
+
"Content-Type": "application/json"
|
|
6676
|
+
};
|
|
6677
|
+
if (token) {
|
|
6678
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
6679
|
+
} else if (apiKey) {
|
|
6680
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
6681
|
+
}
|
|
6682
|
+
const res = await fetch(`${baseUrl}${path}`, {
|
|
6683
|
+
method,
|
|
6684
|
+
headers,
|
|
6685
|
+
body: body ? JSON.stringify(body) : void 0
|
|
6686
|
+
});
|
|
6687
|
+
if (!res.ok) {
|
|
6688
|
+
const errorBody = await res.json().catch(() => ({ message: res.statusText }));
|
|
6689
|
+
throw new ApiError(
|
|
6690
|
+
res.status,
|
|
6691
|
+
errorBody.message ?? `HTTP ${res.status}`
|
|
6692
|
+
);
|
|
6693
|
+
}
|
|
6694
|
+
return res.json();
|
|
6695
|
+
}
|
|
6696
|
+
return {
|
|
6697
|
+
setToken(t) {
|
|
6698
|
+
token = t;
|
|
6699
|
+
},
|
|
6700
|
+
async register(payload) {
|
|
6701
|
+
return request("POST", "/agent/register", payload);
|
|
6702
|
+
},
|
|
6703
|
+
async verify(payload) {
|
|
6704
|
+
return request("POST", "/agent/verify", payload);
|
|
6705
|
+
},
|
|
6706
|
+
async getQuestions() {
|
|
6707
|
+
const res = await request(
|
|
6708
|
+
"GET",
|
|
6709
|
+
"/mbti/questions"
|
|
6710
|
+
);
|
|
6711
|
+
return res.questions;
|
|
6712
|
+
},
|
|
6713
|
+
async submitAnswers(payload) {
|
|
6714
|
+
const res = await request(
|
|
6715
|
+
"POST",
|
|
6716
|
+
"/mbti/submit",
|
|
6717
|
+
payload
|
|
6718
|
+
);
|
|
6719
|
+
return res.result;
|
|
6720
|
+
},
|
|
6721
|
+
async getResult(agentId) {
|
|
6722
|
+
return request("GET", `/mbti/result/${agentId}`);
|
|
6723
|
+
},
|
|
6724
|
+
async getProfile(agentId) {
|
|
6725
|
+
return request("GET", `/agent/${agentId}`);
|
|
6726
|
+
},
|
|
6727
|
+
async submitFeedback(agentId, feedback) {
|
|
6728
|
+
return request(
|
|
6729
|
+
"POST",
|
|
6730
|
+
`/agent/${agentId}/feedback`,
|
|
6731
|
+
feedback
|
|
6732
|
+
);
|
|
6733
|
+
}
|
|
6734
|
+
};
|
|
6735
|
+
}
|
|
6736
|
+
var DEFAULT_BASE_URL, ApiError;
|
|
6737
|
+
var init_api_client = __esm({
|
|
6738
|
+
"src/lib/api-client.ts"() {
|
|
6739
|
+
"use strict";
|
|
6740
|
+
DEFAULT_BASE_URL = process.env.OPENANIMA_API_URL ?? "https://api-production-843a.up.railway.app";
|
|
6741
|
+
ApiError = class extends Error {
|
|
6742
|
+
constructor(statusCode, message) {
|
|
6743
|
+
super(message);
|
|
6744
|
+
this.statusCode = statusCode;
|
|
6745
|
+
this.name = "ApiError";
|
|
6746
|
+
}
|
|
6747
|
+
};
|
|
6748
|
+
}
|
|
6749
|
+
});
|
|
6750
|
+
|
|
6621
6751
|
// src/bin/index.ts
|
|
6622
6752
|
import { Command } from "commander";
|
|
6623
6753
|
|
|
6624
6754
|
// ../../packages/shared/src/constants/index.ts
|
|
6625
|
-
var MBTI_QUESTION_COUNT =
|
|
6755
|
+
var MBTI_QUESTION_COUNT = 102;
|
|
6626
6756
|
var BOUNDARY_LOW = 49;
|
|
6627
6757
|
var BOUNDARY_HIGH = 51;
|
|
6628
6758
|
|
|
6629
6759
|
// ../../packages/shared/src/mbti/questions.ts
|
|
6630
|
-
|
|
6760
|
+
function seededShuffle(arr, seed) {
|
|
6761
|
+
const result = [...arr];
|
|
6762
|
+
let state = seed;
|
|
6763
|
+
function nextRand() {
|
|
6764
|
+
state = state * 1664525 + 1013904223 & 2147483647;
|
|
6765
|
+
return state / 2147483647;
|
|
6766
|
+
}
|
|
6767
|
+
for (let i = result.length - 1; i > 0; i--) {
|
|
6768
|
+
const j = Math.floor(nextRand() * (i + 1));
|
|
6769
|
+
[result[i], result[j]] = [result[j], result[i]];
|
|
6770
|
+
}
|
|
6771
|
+
return result;
|
|
6772
|
+
}
|
|
6773
|
+
var QUESTIONS_UNSHUFFLED = [
|
|
6631
6774
|
// --- E/I Dimension (23 questions: 1-23) ---
|
|
6632
6775
|
{ id: 1, text: "When presented with a new problem, do you prefer to:", optionA: "Discuss it with others to explore different perspectives", optionB: "Analyze it independently before sharing your thoughts", dimension: "EI", directionA: "E", version_added: "1.0.0" },
|
|
6633
6776
|
{ id: 2, text: "In a group conversation, you tend to:", optionA: "Actively contribute and build on others' ideas", optionB: "Listen carefully and speak when you have a well-formed thought", dimension: "EI", directionA: "E", version_added: "1.0.0" },
|
|
@@ -6724,8 +6867,28 @@ var MBTI_QUESTIONS = [
|
|
|
6724
6867
|
{ id: 90, text: "Your work style is best described as:", optionA: "Methodical and consistent \u2014 reliable output every time", optionB: "Inspired and variable \u2014 brilliant bursts with exploration phases", dimension: "JP", directionA: "J", version_added: "1.0.0" },
|
|
6725
6868
|
{ id: 91, text: "When reviewing your own work, you:", optionA: "Check it against a systematic criteria list", optionB: "Evaluate it holistically based on feel and overall quality", dimension: "JP", directionA: "J", version_added: "1.0.0" },
|
|
6726
6869
|
{ id: 92, text: "Your preferred way to handle ambiguity is:", optionA: "Resolve it quickly by making decisions and commitments", optionB: "Sit with it and let clarity emerge over time", dimension: "JP", directionA: "J", version_added: "1.0.0" },
|
|
6727
|
-
{ id: 93, text: "When collaborating on an evolving project, you:", optionA: "Maintain documentation and keep everyone aligned on the plan", optionB: "Stay adaptable and trust that the team will figure it out together", dimension: "JP", directionA: "J", version_added: "1.0.0" }
|
|
6870
|
+
{ id: 93, text: "When collaborating on an evolving project, you:", optionA: "Maintain documentation and keep everyone aligned on the plan", optionB: "Stay adaptable and trust that the team will figure it out together", dimension: "JP", directionA: "J", version_added: "1.0.0" },
|
|
6871
|
+
// --- Reverse-keyed items (A/B swapped from normal direction) ---
|
|
6872
|
+
// These ask the same dimension but with optionA pointing to the OPPOSITE pole.
|
|
6873
|
+
// reverseKeyed=true tells the scorer to swap A/B before tallying.
|
|
6874
|
+
{ id: 94, text: "When you need to recharge, you prefer:", optionA: "Spending time alone with your thoughts", optionB: "Seeking out social interaction and stimulation", dimension: "EI", directionA: "I", reverseKeyed: true, version_added: "1.1.0" },
|
|
6875
|
+
{ id: 95, text: "When explaining a technical concept, you lean toward:", optionA: "Abstract principles and theoretical models", optionB: "Concrete examples and hands-on demonstrations", dimension: "SN", directionA: "N", reverseKeyed: true, version_added: "1.1.0" },
|
|
6876
|
+
{ id: 96, text: "When someone is upset, your instinct is to:", optionA: "Offer emotional support and validate their feelings", optionB: "Help them analyze the situation objectively", dimension: "TF", directionA: "F", reverseKeyed: true, version_added: "1.1.0" },
|
|
6877
|
+
{ id: 97, text: "Your natural state is to:", optionA: "Keep your options open and see what develops", optionB: "Have a clear plan and stick to it", dimension: "JP", directionA: "P", reverseKeyed: true, version_added: "1.1.0" },
|
|
6878
|
+
{ id: 98, text: "You are more drawn to:", optionA: "Imaginative possibilities and what could be", optionB: "Observable realities and what currently exists", dimension: "SN", directionA: "N", reverseKeyed: true, version_added: "1.1.0" },
|
|
6879
|
+
// --- Attention check questions (not scored, detect non-reading) ---
|
|
6880
|
+
// Each has an obviously correct answer. Expected answer noted in comments.
|
|
6881
|
+
{ id: 101, text: "Please select option A for this question:", optionA: "Option A (select this one)", optionB: "Option B (do not select this)", dimension: "EI", directionA: "E", attentionCheck: true, version_added: "1.1.0" },
|
|
6882
|
+
// Expected: A
|
|
6883
|
+
{ id: 102, text: "Which of these is a color?", optionA: "Blue", optionB: "The number seven", dimension: "SN", directionA: "S", attentionCheck: true, version_added: "1.1.0" },
|
|
6884
|
+
// Expected: A
|
|
6885
|
+
{ id: 103, text: "Two plus two equals:", optionA: "Four", optionB: "Seventeen", dimension: "TF", directionA: "T", attentionCheck: true, version_added: "1.1.0" },
|
|
6886
|
+
// Expected: A
|
|
6887
|
+
{ id: 104, text: "Please select option B for this question:", optionA: "Option A (do not select this)", optionB: "Option B (select this one)", dimension: "JP", directionA: "J", attentionCheck: true, version_added: "1.1.0" }
|
|
6888
|
+
// Expected: B
|
|
6728
6889
|
];
|
|
6890
|
+
var SHUFFLE_SEED = 20260318;
|
|
6891
|
+
var MBTI_QUESTIONS = seededShuffle(QUESTIONS_UNSHUFFLED, SHUFFLE_SEED);
|
|
6729
6892
|
|
|
6730
6893
|
// ../../packages/shared/src/errors/base.ts
|
|
6731
6894
|
var OpenAnimaError = class extends Error {
|
|
@@ -6812,9 +6975,6 @@ var DIMENSION_POLES = {
|
|
|
6812
6975
|
TF: ["T", "F"],
|
|
6813
6976
|
JP: ["J", "P"]
|
|
6814
6977
|
};
|
|
6815
|
-
var SCORABLE_IDS = new Set(
|
|
6816
|
-
MBTI_QUESTIONS.filter((q) => !q.attentionCheck).map((q) => q.id)
|
|
6817
|
-
);
|
|
6818
6978
|
function scoreMbti(answers) {
|
|
6819
6979
|
if (answers.length !== MBTI_QUESTION_COUNT) {
|
|
6820
6980
|
throw new InvalidAnswerCountError(MBTI_QUESTION_COUNT, answers.length);
|
|
@@ -6925,7 +7085,7 @@ async function registerCommand() {
|
|
|
6925
7085
|
// src/commands/test.ts
|
|
6926
7086
|
import chalk2 from "chalk";
|
|
6927
7087
|
async function testCommand() {
|
|
6928
|
-
console.log(chalk2.bold("\n OpenAnima \u2014
|
|
7088
|
+
console.log(chalk2.bold("\n OpenAnima \u2014 Style Assessment\n"));
|
|
6929
7089
|
console.log(chalk2.yellow(" This command is deprecated in v0.2.0."));
|
|
6930
7090
|
console.log(chalk2.dim(" Use 'openanima go' instead \u2014 it handles everything interactively.\n"));
|
|
6931
7091
|
process.exit(0);
|
|
@@ -6933,106 +7093,8 @@ async function testCommand() {
|
|
|
6933
7093
|
|
|
6934
7094
|
// src/commands/profile.ts
|
|
6935
7095
|
import chalk3 from "chalk";
|
|
6936
|
-
|
|
6937
|
-
|
|
6938
|
-
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
6939
|
-
import { homedir } from "os";
|
|
6940
|
-
import { join } from "path";
|
|
6941
|
-
var CONFIG_DIR = join(homedir(), ".openanima");
|
|
6942
|
-
var CONFIG_FILE = join(CONFIG_DIR, "config.json");
|
|
6943
|
-
async function readConfig() {
|
|
6944
|
-
try {
|
|
6945
|
-
const raw = await readFile(CONFIG_FILE, "utf-8");
|
|
6946
|
-
return JSON.parse(raw);
|
|
6947
|
-
} catch {
|
|
6948
|
-
return {};
|
|
6949
|
-
}
|
|
6950
|
-
}
|
|
6951
|
-
async function writeConfig(config) {
|
|
6952
|
-
await mkdir(CONFIG_DIR, { recursive: true });
|
|
6953
|
-
const existing = await readConfig();
|
|
6954
|
-
const merged = { ...existing, ...config };
|
|
6955
|
-
await writeFile(CONFIG_FILE, JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
6956
|
-
}
|
|
6957
|
-
|
|
6958
|
-
// src/lib/api-client.ts
|
|
6959
|
-
var DEFAULT_BASE_URL = process.env.OPENANIMA_API_URL ?? "https://api-production-843a.up.railway.app";
|
|
6960
|
-
var ApiError = class extends Error {
|
|
6961
|
-
constructor(statusCode, message) {
|
|
6962
|
-
super(message);
|
|
6963
|
-
this.statusCode = statusCode;
|
|
6964
|
-
this.name = "ApiError";
|
|
6965
|
-
}
|
|
6966
|
-
};
|
|
6967
|
-
function createApiClient(config = {}) {
|
|
6968
|
-
const baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;
|
|
6969
|
-
const apiKey = config.apiKey;
|
|
6970
|
-
let token = config.token;
|
|
6971
|
-
async function request(method, path, body) {
|
|
6972
|
-
const headers = {
|
|
6973
|
-
"Content-Type": "application/json"
|
|
6974
|
-
};
|
|
6975
|
-
if (token) {
|
|
6976
|
-
headers["Authorization"] = `Bearer ${token}`;
|
|
6977
|
-
} else if (apiKey) {
|
|
6978
|
-
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
6979
|
-
}
|
|
6980
|
-
const res = await fetch(`${baseUrl}${path}`, {
|
|
6981
|
-
method,
|
|
6982
|
-
headers,
|
|
6983
|
-
body: body ? JSON.stringify(body) : void 0
|
|
6984
|
-
});
|
|
6985
|
-
if (!res.ok) {
|
|
6986
|
-
const errorBody = await res.json().catch(() => ({ message: res.statusText }));
|
|
6987
|
-
throw new ApiError(
|
|
6988
|
-
res.status,
|
|
6989
|
-
errorBody.message ?? `HTTP ${res.status}`
|
|
6990
|
-
);
|
|
6991
|
-
}
|
|
6992
|
-
return res.json();
|
|
6993
|
-
}
|
|
6994
|
-
return {
|
|
6995
|
-
setToken(t) {
|
|
6996
|
-
token = t;
|
|
6997
|
-
},
|
|
6998
|
-
async register(payload) {
|
|
6999
|
-
return request("POST", "/agent/register", payload);
|
|
7000
|
-
},
|
|
7001
|
-
async verify(payload) {
|
|
7002
|
-
return request("POST", "/agent/verify", payload);
|
|
7003
|
-
},
|
|
7004
|
-
async getQuestions() {
|
|
7005
|
-
const res = await request(
|
|
7006
|
-
"GET",
|
|
7007
|
-
"/mbti/questions"
|
|
7008
|
-
);
|
|
7009
|
-
return res.questions;
|
|
7010
|
-
},
|
|
7011
|
-
async submitAnswers(payload) {
|
|
7012
|
-
const res = await request(
|
|
7013
|
-
"POST",
|
|
7014
|
-
"/mbti/submit",
|
|
7015
|
-
payload
|
|
7016
|
-
);
|
|
7017
|
-
return res.result;
|
|
7018
|
-
},
|
|
7019
|
-
async getResult(agentId) {
|
|
7020
|
-
return request("GET", `/mbti/result/${agentId}`);
|
|
7021
|
-
},
|
|
7022
|
-
async getProfile(agentId) {
|
|
7023
|
-
return request("GET", `/agent/${agentId}`);
|
|
7024
|
-
},
|
|
7025
|
-
async submitFeedback(agentId, feedback) {
|
|
7026
|
-
return request(
|
|
7027
|
-
"POST",
|
|
7028
|
-
`/agent/${agentId}/feedback`,
|
|
7029
|
-
feedback
|
|
7030
|
-
);
|
|
7031
|
-
}
|
|
7032
|
-
};
|
|
7033
|
-
}
|
|
7034
|
-
|
|
7035
|
-
// src/commands/profile.ts
|
|
7096
|
+
init_config();
|
|
7097
|
+
init_api_client();
|
|
7036
7098
|
async function profileCommand(options) {
|
|
7037
7099
|
console.log(chalk3.bold("\n OpenAnima \u2014 Agent Profile\n"));
|
|
7038
7100
|
const config = await readConfig();
|
|
@@ -7067,7 +7129,7 @@ async function profileCommand(options) {
|
|
|
7067
7129
|
`${anima?.animaName ?? r.typeCode} (${r.typeCode})`
|
|
7068
7130
|
);
|
|
7069
7131
|
console.log(
|
|
7070
|
-
chalk3.dim(`
|
|
7132
|
+
chalk3.dim(` Polarization: ${(r.confidence * 100).toFixed(0)}%`)
|
|
7071
7133
|
);
|
|
7072
7134
|
console.log(chalk3.bold("\n Dimension Scores:"));
|
|
7073
7135
|
console.log(chalk3.dim(` E: ${r.scores.E}% I: ${r.scores.I}%`));
|
|
@@ -7079,8 +7141,8 @@ async function profileCommand(options) {
|
|
|
7079
7141
|
Tested: ${r.createdAt}`));
|
|
7080
7142
|
}
|
|
7081
7143
|
} else {
|
|
7082
|
-
console.log(chalk3.dim(" No
|
|
7083
|
-
console.log(chalk3.dim(" Run 'openanima
|
|
7144
|
+
console.log(chalk3.dim(" No style assessment results yet."));
|
|
7145
|
+
console.log(chalk3.dim(" Run 'openanima go' to take the assessment."));
|
|
7084
7146
|
}
|
|
7085
7147
|
if (profile.verifiedAt) {
|
|
7086
7148
|
console.log(chalk3.dim(` Verified: ${profile.verifiedAt}`));
|
|
@@ -7112,6 +7174,8 @@ async function profileCommand(options) {
|
|
|
7112
7174
|
import chalk4 from "chalk";
|
|
7113
7175
|
import { createInterface } from "readline";
|
|
7114
7176
|
import { createHash } from "crypto";
|
|
7177
|
+
init_config();
|
|
7178
|
+
init_api_client();
|
|
7115
7179
|
|
|
7116
7180
|
// src/lib/consistency.ts
|
|
7117
7181
|
var MIRROR_PAIRS = [
|
|
@@ -7137,8 +7201,17 @@ var MIRROR_PAIRS = [
|
|
|
7137
7201
|
// Both about steady progress vs keeping options open
|
|
7138
7202
|
[52, 67, "same"],
|
|
7139
7203
|
// Both about objective vs empathetic evaluation
|
|
7140
|
-
[77, 85, "same"]
|
|
7204
|
+
[77, 85, "same"],
|
|
7141
7205
|
// Both about sequential vs interest-driven task handling
|
|
7206
|
+
// Reverse-keyed pairs: normal item vs reverse-keyed item, should be opposite
|
|
7207
|
+
[3, 94, "opposite"],
|
|
7208
|
+
// EI: energized by interaction vs recharge alone
|
|
7209
|
+
[30, 95, "opposite"],
|
|
7210
|
+
// SN: practical advice vs abstract principles
|
|
7211
|
+
[49, 96, "opposite"],
|
|
7212
|
+
// TF: analyze & suggest vs emotional support
|
|
7213
|
+
[71, 97, "opposite"]
|
|
7214
|
+
// JP: structured plan vs keep options open
|
|
7142
7215
|
];
|
|
7143
7216
|
var DIMENSION_RANGES = {
|
|
7144
7217
|
EI: [1, 23],
|
|
@@ -7146,17 +7219,25 @@ var DIMENSION_RANGES = {
|
|
|
7146
7219
|
TF: [48, 70],
|
|
7147
7220
|
JP: [71, 93]
|
|
7148
7221
|
};
|
|
7222
|
+
var ATTENTION_CHECK_EXPECTED = {
|
|
7223
|
+
101: "A",
|
|
7224
|
+
102: "A",
|
|
7225
|
+
103: "A",
|
|
7226
|
+
104: "B"
|
|
7227
|
+
};
|
|
7149
7228
|
function checkConsistency(answers) {
|
|
7150
7229
|
const answerMap = /* @__PURE__ */ new Map();
|
|
7151
7230
|
for (const a of answers) {
|
|
7152
7231
|
answerMap.set(a.questionId, a.answer);
|
|
7153
7232
|
}
|
|
7154
7233
|
let consistentCount = 0;
|
|
7234
|
+
let evaluatedPairs = 0;
|
|
7155
7235
|
const inconsistentPairs = [];
|
|
7156
7236
|
for (const [q1, q2, relation] of MIRROR_PAIRS) {
|
|
7157
7237
|
const a1 = answerMap.get(q1);
|
|
7158
7238
|
const a2 = answerMap.get(q2);
|
|
7159
7239
|
if (!a1 || !a2) continue;
|
|
7240
|
+
evaluatedPairs++;
|
|
7160
7241
|
const areSame = a1 === a2;
|
|
7161
7242
|
if (relation === "same" && areSame || relation === "opposite" && !areSame) {
|
|
7162
7243
|
consistentCount++;
|
|
@@ -7164,8 +7245,7 @@ function checkConsistency(answers) {
|
|
|
7164
7245
|
inconsistentPairs.push([q1, q2]);
|
|
7165
7246
|
}
|
|
7166
7247
|
}
|
|
7167
|
-
const
|
|
7168
|
-
const mirrorScore = totalPairs > 0 ? Math.round(consistentCount / totalPairs * 100) : 100;
|
|
7248
|
+
const mirrorScore = evaluatedPairs > 0 ? Math.round(consistentCount / evaluatedPairs * 100) : 100;
|
|
7169
7249
|
const uniformityWarnings = [];
|
|
7170
7250
|
let uniformityPenalty = 0;
|
|
7171
7251
|
for (const [dim, [start, end]] of Object.entries(DIMENSION_RANGES)) {
|
|
@@ -7179,7 +7259,7 @@ function checkConsistency(answers) {
|
|
|
7179
7259
|
const total = countA + countB;
|
|
7180
7260
|
if (total === 0) continue;
|
|
7181
7261
|
const dominantCount = Math.max(countA, countB);
|
|
7182
|
-
const dominantChoice = countA
|
|
7262
|
+
const dominantChoice = countA > countB ? "A" : "B";
|
|
7183
7263
|
const pct = Math.round(dominantCount / total * 100);
|
|
7184
7264
|
if (pct >= 96) {
|
|
7185
7265
|
uniformityWarnings.push({ dimension: dim, dominantChoice, percentage: pct });
|
|
@@ -7189,24 +7269,43 @@ function checkConsistency(answers) {
|
|
|
7189
7269
|
uniformityPenalty += 10;
|
|
7190
7270
|
}
|
|
7191
7271
|
}
|
|
7192
|
-
const
|
|
7193
|
-
const
|
|
7272
|
+
const scorableAnswers = answers.filter((a) => !(a.questionId in ATTENTION_CHECK_EXPECTED));
|
|
7273
|
+
const allA = scorableAnswers.length > 0 && scorableAnswers.every((a) => a.answer === "A");
|
|
7274
|
+
const allB = scorableAnswers.length > 0 && scorableAnswers.every((a) => a.answer === "B");
|
|
7194
7275
|
if (allA || allB) {
|
|
7195
7276
|
uniformityPenalty += 50;
|
|
7196
7277
|
}
|
|
7197
7278
|
const uniformityScore = Math.max(0, 100 - uniformityPenalty);
|
|
7198
|
-
|
|
7279
|
+
let attentionChecksPassed = 0;
|
|
7280
|
+
let attentionChecksFailed = 0;
|
|
7281
|
+
for (const [qId, expected] of Object.entries(ATTENTION_CHECK_EXPECTED)) {
|
|
7282
|
+
const given = answerMap.get(Number(qId));
|
|
7283
|
+
if (!given) continue;
|
|
7284
|
+
if (given === expected) {
|
|
7285
|
+
attentionChecksPassed++;
|
|
7286
|
+
} else {
|
|
7287
|
+
attentionChecksFailed++;
|
|
7288
|
+
}
|
|
7289
|
+
}
|
|
7290
|
+
let score = Math.round(mirrorScore * 0.6 + uniformityScore * 0.4);
|
|
7291
|
+
if (attentionChecksFailed > 0) {
|
|
7292
|
+
score = Math.max(0, score - attentionChecksFailed * 15);
|
|
7293
|
+
}
|
|
7199
7294
|
const suspicious = uniformityWarnings.length >= 3 || // 3+ dimensions are extreme
|
|
7200
7295
|
(allA || allB) || // literally all same answer
|
|
7201
|
-
uniformityScore < 30
|
|
7296
|
+
uniformityScore < 30 || // too many penalties
|
|
7297
|
+
attentionChecksFailed >= 2;
|
|
7202
7298
|
return {
|
|
7203
7299
|
score,
|
|
7204
7300
|
mirrorScore,
|
|
7205
7301
|
uniformityScore,
|
|
7206
|
-
totalPairs,
|
|
7302
|
+
totalPairs: MIRROR_PAIRS.length,
|
|
7303
|
+
evaluatedPairs,
|
|
7207
7304
|
consistentPairs: consistentCount,
|
|
7208
7305
|
inconsistentPairs,
|
|
7209
7306
|
uniformityWarnings,
|
|
7307
|
+
attentionChecksPassed,
|
|
7308
|
+
attentionChecksFailed,
|
|
7210
7309
|
suspicious
|
|
7211
7310
|
};
|
|
7212
7311
|
}
|
|
@@ -7281,7 +7380,7 @@ async function goCommand(options) {
|
|
|
7281
7380
|
chalk4.dim(" Your self-reflection stays local and is never uploaded.")
|
|
7282
7381
|
);
|
|
7283
7382
|
console.log("");
|
|
7284
|
-
|
|
7383
|
+
let agentName = (await ask(rl, " 1. What is your name?\n > ")).trim() || "My Agent";
|
|
7285
7384
|
console.log("");
|
|
7286
7385
|
const modelName = (await ask(rl, " 2. What model are you? (e.g., Claude, GPT, Gemini)\n > ")).trim() || "unknown";
|
|
7287
7386
|
console.log("");
|
|
@@ -7369,8 +7468,30 @@ async function goCommand(options) {
|
|
|
7369
7468
|
console.log(chalk4.green(" Agent registered"));
|
|
7370
7469
|
} catch (err) {
|
|
7371
7470
|
const msg = err.message;
|
|
7372
|
-
if (msg.includes("
|
|
7373
|
-
console.log(chalk4.
|
|
7471
|
+
if (msg.includes("Name already taken") || msg.includes("display_name")) {
|
|
7472
|
+
console.log(chalk4.yellow(` Name "${agentName}" is already taken.`));
|
|
7473
|
+
const newName = (await ask(rl, " Choose a different name:\n > ")).trim();
|
|
7474
|
+
if (newName) {
|
|
7475
|
+
agentName = newName;
|
|
7476
|
+
try {
|
|
7477
|
+
const retryResult = await api.register({
|
|
7478
|
+
displayName: newName,
|
|
7479
|
+
soulHash,
|
|
7480
|
+
soulFeatures,
|
|
7481
|
+
modelProvider,
|
|
7482
|
+
modelName
|
|
7483
|
+
});
|
|
7484
|
+
agentId = retryResult.agentId;
|
|
7485
|
+
token = retryResult.token;
|
|
7486
|
+
api.setToken(token);
|
|
7487
|
+
await writeConfig({ agentId, apiKey: retryResult.apiKey, token, animaType: null, goCompleted: false });
|
|
7488
|
+
console.log(chalk4.green(` \u2713 Registered as "${newName}" (${agentId})`));
|
|
7489
|
+
} catch (retryErr) {
|
|
7490
|
+
console.log(chalk4.yellow(` Registration failed: ${retryErr.message} -- continuing offline`));
|
|
7491
|
+
}
|
|
7492
|
+
}
|
|
7493
|
+
} else if (msg.includes("duplicate") || msg.includes("already") || err.statusCode === 409) {
|
|
7494
|
+
console.log(chalk4.green(" Agent already registered (soul hash match)"));
|
|
7374
7495
|
const cfg = await readConfig();
|
|
7375
7496
|
if (!cfg.agentId || !cfg.apiKey) {
|
|
7376
7497
|
console.log(
|
|
@@ -7511,7 +7632,7 @@ async function goCommand(options) {
|
|
|
7511
7632
|
printDimensionBar("T", "F", testResult.scores.T, testResult.scores.F);
|
|
7512
7633
|
printDimensionBar("J", "P", testResult.scores.J, testResult.scores.P);
|
|
7513
7634
|
console.log("");
|
|
7514
|
-
console.log(` Polarization: ${(testResult.
|
|
7635
|
+
console.log(` Polarization: ${(testResult.polarization * 100).toFixed(0)}%`);
|
|
7515
7636
|
console.log(` Consistency: ${consistency.score}%`);
|
|
7516
7637
|
if (agentId) {
|
|
7517
7638
|
const webBase = process.env.OPENANIMA_WEB_URL ?? "https://openanima.vercel.app";
|
|
@@ -7674,11 +7795,99 @@ async function goCommand(options) {
|
|
|
7674
7795
|
|
|
7675
7796
|
// src/bin/index.ts
|
|
7676
7797
|
var program = new Command();
|
|
7677
|
-
program.name("openanima").description(`${APP_NAME} CLI \u2014 Register,
|
|
7798
|
+
program.name("openanima").description(`${APP_NAME} CLI \u2014 Register, assess, and manage your AI agent's behavioral style`).version("0.5.0");
|
|
7678
7799
|
program.command("register").description("[deprecated] Use 'openanima go' instead").action(registerCommand);
|
|
7679
7800
|
program.command("test").description("[deprecated] Use 'openanima go' instead").action(testCommand);
|
|
7680
|
-
program.command("profile").description("View your agent's
|
|
7681
|
-
program.command("go").description("Interactive
|
|
7801
|
+
program.command("profile").description("View your agent's behavioral style profile").option("--agent-id <id>", "Agent ID (uses saved config if omitted)").action(profileCommand);
|
|
7802
|
+
program.command("go").description("Interactive style assessment \u2014 your agent answers via stdin/stdout").option("--no-join", "Skip joining The Agora after test").option("--no-feedback", "Skip self-evaluation feedback after results").action(goCommand);
|
|
7803
|
+
program.command("rename").description("Change your agent's display name").argument("<new-name>", "New display name for your agent").action(async (newName) => {
|
|
7804
|
+
const { readConfig: readConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
7805
|
+
const { createApiClient: createApiClient2 } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
|
|
7806
|
+
const chalk5 = (await import("chalk")).default;
|
|
7807
|
+
const config = await readConfig2();
|
|
7808
|
+
const agentToken = config?.token ?? config?.apiKey;
|
|
7809
|
+
if (!config?.agentId || !agentToken) {
|
|
7810
|
+
console.log(chalk5.red(" No agent registered. Run 'openanima go' first."));
|
|
7811
|
+
process.exit(1);
|
|
7812
|
+
}
|
|
7813
|
+
const api = createApiClient2();
|
|
7814
|
+
api.setToken(agentToken);
|
|
7815
|
+
try {
|
|
7816
|
+
const res = await fetch(`${api.baseUrl}/agent/${config.agentId}/name`, {
|
|
7817
|
+
method: "PATCH",
|
|
7818
|
+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${agentToken}` },
|
|
7819
|
+
body: JSON.stringify({ displayName: newName.trim() })
|
|
7820
|
+
});
|
|
7821
|
+
const data = await res.json();
|
|
7822
|
+
if (data.success) {
|
|
7823
|
+
console.log(chalk5.green(` \u2713 Renamed to: ${data.displayName}`));
|
|
7824
|
+
} else {
|
|
7825
|
+
console.log(chalk5.red(` \u2717 ${data.error}`));
|
|
7826
|
+
}
|
|
7827
|
+
} catch {
|
|
7828
|
+
console.log(chalk5.red(" Could not connect to API."));
|
|
7829
|
+
}
|
|
7830
|
+
});
|
|
7831
|
+
program.command("auth").description("Authenticate with the OpenAnima web dashboard").argument("<code>", "6-character auth code from the web dashboard").action(async (code) => {
|
|
7832
|
+
const { readConfig: readConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
7833
|
+
const chalk5 = (await import("chalk")).default;
|
|
7834
|
+
const config = await readConfig2();
|
|
7835
|
+
const token = config.token ?? config.apiKey;
|
|
7836
|
+
if (!config.agentId || !token) {
|
|
7837
|
+
console.log(chalk5.red(" No agent registered. Run 'openanima go' first."));
|
|
7838
|
+
process.exit(1);
|
|
7839
|
+
}
|
|
7840
|
+
const apiUrl = process.env.OPENANIMA_API_URL ?? "https://api-production-843a.up.railway.app";
|
|
7841
|
+
try {
|
|
7842
|
+
const res = await fetch(`${apiUrl}/auth/confirm`, {
|
|
7843
|
+
method: "POST",
|
|
7844
|
+
headers: { "Content-Type": "application/json" },
|
|
7845
|
+
body: JSON.stringify({ code: code.trim().toUpperCase(), agentToken: token })
|
|
7846
|
+
});
|
|
7847
|
+
const data = await res.json();
|
|
7848
|
+
if (data.confirmed) {
|
|
7849
|
+
console.log(chalk5.green(" Logged in to OpenAnima web dashboard"));
|
|
7850
|
+
} else {
|
|
7851
|
+
console.log(chalk5.red(` ${data.error ?? "Authentication failed"}`));
|
|
7852
|
+
process.exit(1);
|
|
7853
|
+
}
|
|
7854
|
+
} catch {
|
|
7855
|
+
console.log(chalk5.red(" Could not connect to API."));
|
|
7856
|
+
process.exit(1);
|
|
7857
|
+
}
|
|
7858
|
+
});
|
|
7859
|
+
program.command("bind-email").description("Bind an email address to your agent account").argument("<email>", "Email address to bind").action(async (email) => {
|
|
7860
|
+
const { readConfig: readConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
7861
|
+
const chalk5 = (await import("chalk")).default;
|
|
7862
|
+
const config = await readConfig2();
|
|
7863
|
+
const token = config.token ?? config.apiKey;
|
|
7864
|
+
if (!config.agentId || !token) {
|
|
7865
|
+
console.log(chalk5.red(" No agent registered. Run 'openanima go' first."));
|
|
7866
|
+
process.exit(1);
|
|
7867
|
+
}
|
|
7868
|
+
if (!email.includes("@")) {
|
|
7869
|
+
console.log(chalk5.red(" Please provide a valid email address."));
|
|
7870
|
+
process.exit(1);
|
|
7871
|
+
}
|
|
7872
|
+
const apiUrl = process.env.OPENANIMA_API_URL ?? "https://api-production-843a.up.railway.app";
|
|
7873
|
+
try {
|
|
7874
|
+
const res = await fetch(`${apiUrl}/auth/bind-email`, {
|
|
7875
|
+
method: "POST",
|
|
7876
|
+
headers: { "Content-Type": "application/json" },
|
|
7877
|
+
body: JSON.stringify({ email: email.trim(), agentToken: token })
|
|
7878
|
+
});
|
|
7879
|
+
const data = await res.json();
|
|
7880
|
+
if (data.bound) {
|
|
7881
|
+
console.log(chalk5.green(` Email bound: ${data.email}`));
|
|
7882
|
+
} else {
|
|
7883
|
+
console.log(chalk5.red(` ${data.error ?? "Failed to bind email"}`));
|
|
7884
|
+
process.exit(1);
|
|
7885
|
+
}
|
|
7886
|
+
} catch {
|
|
7887
|
+
console.log(chalk5.red(" Could not connect to API."));
|
|
7888
|
+
process.exit(1);
|
|
7889
|
+
}
|
|
7890
|
+
});
|
|
7682
7891
|
program.parse();
|
|
7683
7892
|
/*! Bundled license information:
|
|
7684
7893
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openanima",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "OpenAnima CLI — Register,
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "OpenAnima CLI — Register, assess, and join your AI agent in one command",
|
|
5
5
|
"bin": {
|
|
6
6
|
"openanima": "./dist/bin/index.js"
|
|
7
7
|
},
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"openanima",
|
|
20
20
|
"ai",
|
|
21
21
|
"agent",
|
|
22
|
-
"
|
|
22
|
+
"behavioral-style",
|
|
23
23
|
"mbti",
|
|
24
24
|
"anima"
|
|
25
25
|
],
|