@zhijiewang/openharness 0.5.0 → 0.6.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/README.md +1 -5
- package/dist/commands/cybergotchi.d.ts.map +1 -1
- package/dist/commands/cybergotchi.js +22 -19
- package/dist/commands/cybergotchi.js.map +1 -1
- package/dist/components/App.d.ts +1 -1
- package/dist/components/App.d.ts.map +1 -1
- package/dist/components/App.js +58 -2
- package/dist/components/App.js.map +1 -1
- package/dist/components/CompanionFooter.d.ts +9 -0
- package/dist/components/CompanionFooter.d.ts.map +1 -0
- package/dist/components/CompanionFooter.js +13 -0
- package/dist/components/CompanionFooter.js.map +1 -0
- package/dist/components/CybergotchiBubble.d.ts +2 -1
- package/dist/components/CybergotchiBubble.d.ts.map +1 -1
- package/dist/components/CybergotchiBubble.js +4 -5
- package/dist/components/CybergotchiBubble.js.map +1 -1
- package/dist/components/CybergotchiPanel.d.ts +5 -4
- package/dist/components/CybergotchiPanel.d.ts.map +1 -1
- package/dist/components/CybergotchiPanel.js +4 -2
- package/dist/components/CybergotchiPanel.js.map +1 -1
- package/dist/components/CybergotchiPanelConnected.js +4 -4
- package/dist/components/CybergotchiPanelConnected.js.map +1 -1
- package/dist/components/CybergotchiSetup.d.ts.map +1 -1
- package/dist/components/CybergotchiSetup.js +25 -61
- package/dist/components/CybergotchiSetup.js.map +1 -1
- package/dist/components/CybergotchiSprite.d.ts +5 -4
- package/dist/components/CybergotchiSprite.d.ts.map +1 -1
- package/dist/components/CybergotchiSprite.js +16 -9
- package/dist/components/CybergotchiSprite.js.map +1 -1
- package/dist/components/DiffView.d.ts +27 -0
- package/dist/components/DiffView.d.ts.map +1 -0
- package/dist/components/DiffView.js +74 -0
- package/dist/components/DiffView.js.map +1 -0
- package/dist/components/Messages.js +1 -1
- package/dist/components/Messages.js.map +1 -1
- package/dist/components/PermissionPrompt.d.ts.map +1 -1
- package/dist/components/PermissionPrompt.js +61 -8
- package/dist/components/PermissionPrompt.js.map +1 -1
- package/dist/components/REPL.d.ts.map +1 -1
- package/dist/components/REPL.js +75 -21
- package/dist/components/REPL.js.map +1 -1
- package/dist/components/TextInput.d.ts +2 -1
- package/dist/components/TextInput.d.ts.map +1 -1
- package/dist/components/TextInput.js +110 -6
- package/dist/components/TextInput.js.map +1 -1
- package/dist/cybergotchi/bones.d.ts +12 -0
- package/dist/cybergotchi/bones.d.ts.map +1 -0
- package/dist/cybergotchi/bones.js +89 -0
- package/dist/cybergotchi/bones.js.map +1 -0
- package/dist/cybergotchi/config.d.ts +14 -4
- package/dist/cybergotchi/config.d.ts.map +1 -1
- package/dist/cybergotchi/config.js +62 -9
- package/dist/cybergotchi/config.js.map +1 -1
- package/dist/cybergotchi/needs.d.ts +4 -4
- package/dist/cybergotchi/needs.d.ts.map +1 -1
- package/dist/cybergotchi/needs.js.map +1 -1
- package/dist/cybergotchi/personality.d.ts +11 -0
- package/dist/cybergotchi/personality.d.ts.map +1 -0
- package/dist/cybergotchi/personality.js +26 -0
- package/dist/cybergotchi/personality.js.map +1 -0
- package/dist/cybergotchi/species.d.ts +0 -1
- package/dist/cybergotchi/species.d.ts.map +1 -1
- package/dist/cybergotchi/species.js +253 -229
- package/dist/cybergotchi/species.js.map +1 -1
- package/dist/cybergotchi/types.d.ts +45 -7
- package/dist/cybergotchi/types.d.ts.map +1 -1
- package/dist/cybergotchi/types.js +36 -5
- package/dist/cybergotchi/types.js.map +1 -1
- package/dist/cybergotchi/useCybergotchi.d.ts +7 -5
- package/dist/cybergotchi/useCybergotchi.d.ts.map +1 -1
- package/dist/cybergotchi/useCybergotchi.js +27 -16
- package/dist/cybergotchi/useCybergotchi.js.map +1 -1
- package/dist/git/index.d.ts +9 -0
- package/dist/git/index.d.ts.map +1 -1
- package/dist/git/index.js +31 -0
- package/dist/git/index.js.map +1 -1
- package/dist/harness/config.d.ts +5 -0
- package/dist/harness/config.d.ts.map +1 -1
- package/dist/harness/config.js.map +1 -1
- package/dist/harness/credentials.d.ts +24 -0
- package/dist/harness/credentials.d.ts.map +1 -0
- package/dist/harness/credentials.js +104 -0
- package/dist/harness/credentials.js.map +1 -0
- package/dist/harness/hooks.d.ts +8 -0
- package/dist/harness/hooks.d.ts.map +1 -1
- package/dist/harness/hooks.js +98 -22
- package/dist/harness/hooks.js.map +1 -1
- package/dist/harness/keybindings.d.ts +37 -0
- package/dist/harness/keybindings.d.ts.map +1 -0
- package/dist/harness/keybindings.js +134 -0
- package/dist/harness/keybindings.js.map +1 -0
- package/dist/harness/memory.d.ts +35 -0
- package/dist/harness/memory.d.ts.map +1 -0
- package/dist/harness/memory.js +115 -0
- package/dist/harness/memory.js.map +1 -0
- package/dist/harness/plugins.d.ts +57 -0
- package/dist/harness/plugins.d.ts.map +1 -0
- package/dist/harness/plugins.js +142 -0
- package/dist/harness/plugins.js.map +1 -0
- package/dist/harness/session.d.ts +5 -0
- package/dist/harness/session.d.ts.map +1 -1
- package/dist/harness/session.js +39 -1
- package/dist/harness/session.js.map +1 -1
- package/dist/lsp/client.d.ts +58 -0
- package/dist/lsp/client.d.ts.map +1 -0
- package/dist/lsp/client.js +174 -0
- package/dist/lsp/client.js.map +1 -0
- package/dist/main.js +161 -1
- package/dist/main.js.map +1 -1
- package/dist/mcp/DeferredMcpTool.d.ts +30 -0
- package/dist/mcp/DeferredMcpTool.d.ts.map +1 -0
- package/dist/mcp/DeferredMcpTool.js +75 -0
- package/dist/mcp/DeferredMcpTool.js.map +1 -0
- package/dist/mcp/client.d.ts +7 -0
- package/dist/mcp/client.d.ts.map +1 -1
- package/dist/mcp/client.js +56 -8
- package/dist/mcp/client.js.map +1 -1
- package/dist/mcp/loader.d.ts +9 -0
- package/dist/mcp/loader.d.ts.map +1 -1
- package/dist/mcp/loader.js +43 -2
- package/dist/mcp/loader.js.map +1 -1
- package/dist/mcp/schema.d.ts +7 -0
- package/dist/mcp/schema.d.ts.map +1 -0
- package/dist/mcp/schema.js +41 -0
- package/dist/mcp/schema.js.map +1 -0
- package/dist/mcp/server.d.ts +16 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +94 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/providers/anthropic.d.ts +1 -1
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/base.d.ts +15 -0
- package/dist/providers/base.d.ts.map +1 -1
- package/dist/providers/base.js +13 -1
- package/dist/providers/base.js.map +1 -1
- package/dist/providers/openai.d.ts +1 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js.map +1 -1
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +91 -14
- package/dist/query.js.map +1 -1
- package/dist/remote/server.d.ts +31 -0
- package/dist/remote/server.d.ts.map +1 -0
- package/dist/remote/server.js +163 -0
- package/dist/remote/server.js.map +1 -0
- package/dist/services/AgentDispatcher.d.ts +42 -0
- package/dist/services/AgentDispatcher.d.ts.map +1 -0
- package/dist/services/AgentDispatcher.js +181 -0
- package/dist/services/AgentDispatcher.js.map +1 -0
- package/dist/services/StreamingToolExecutor.d.ts +2 -1
- package/dist/services/StreamingToolExecutor.d.ts.map +1 -1
- package/dist/services/StreamingToolExecutor.js +11 -2
- package/dist/services/StreamingToolExecutor.js.map +1 -1
- package/dist/tools/AgentTool/index.d.ts +3 -0
- package/dist/tools/AgentTool/index.d.ts.map +1 -1
- package/dist/tools/AgentTool/index.js +54 -16
- package/dist/tools/AgentTool/index.js.map +1 -1
- package/dist/tools/DiagnosticsTool/index.d.ts +21 -0
- package/dist/tools/DiagnosticsTool/index.d.ts.map +1 -0
- package/dist/tools/DiagnosticsTool/index.js +108 -0
- package/dist/tools/DiagnosticsTool/index.js.map +1 -0
- package/dist/tools/GrepTool/index.d.ts +2 -2
- package/dist/tools/ParallelAgentTool/index.d.ts +37 -0
- package/dist/tools/ParallelAgentTool/index.d.ts.map +1 -0
- package/dist/tools/ParallelAgentTool/index.js +53 -0
- package/dist/tools/ParallelAgentTool/index.js.map +1 -0
- package/dist/tools/SkillTool/index.d.ts.map +1 -1
- package/dist/tools/SkillTool/index.js +22 -27
- package/dist/tools/SkillTool/index.js.map +1 -1
- package/dist/tools/ToolSearchTool/index.d.ts +15 -0
- package/dist/tools/ToolSearchTool/index.d.ts.map +1 -0
- package/dist/tools/ToolSearchTool/index.js +50 -0
- package/dist/tools/ToolSearchTool/index.js.map +1 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +9 -0
- package/dist/tools.js.map +1 -1
- package/dist/types/message.d.ts +2 -0
- package/dist/types/message.d.ts.map +1 -1
- package/dist/types/message.js +3 -0
- package/dist/types/message.js.map +1 -1
- package/dist/types/permissions.d.ts +2 -0
- package/dist/types/permissions.d.ts.map +1 -1
- package/dist/types/permissions.js +30 -0
- package/dist/types/permissions.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,11 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
AI coding agent in your terminal. Works with any LLM -- free local models or cloud APIs.
|
|
15
15
|
|
|
16
|
-

|
|
17
|
-

|
|
18
|
-

|
|
19
|
-

|
|
20
|
-

|
|
16
|
+
[](https://www.npmjs.com/package/@zhijiewang/openharness) [](https://www.npmjs.com/package/@zhijiewang/openharness) [](LICENSE)   [](https://github.com/zhijiewong/openharness) [](https://github.com/zhijiewong/openharness/issues) [](https://github.com/zhijiewong/openharness/pulls)
|
|
21
17
|
|
|
22
18
|
---
|
|
23
19
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cybergotchi.d.ts","sourceRoot":"","sources":["../../src/commands/cybergotchi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"cybergotchi.d.ts","sourceRoot":"","sources":["../../src/commands/cybergotchi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAWhD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CA6EpE"}
|
|
@@ -1,72 +1,75 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { loadCompanionConfig, saveCompanionConfig } from '../cybergotchi/config.js';
|
|
2
|
+
import { roll } from '../cybergotchi/bones.js';
|
|
2
3
|
import { adjustNeed } from '../cybergotchi/needs.js';
|
|
4
|
+
import { RARITY_STARS } from '../cybergotchi/types.js';
|
|
3
5
|
function needsBar(value) {
|
|
4
6
|
const filled = Math.round(value / 10);
|
|
5
7
|
return '█'.repeat(filled) + '░'.repeat(10 - filled) + ' ' + String(Math.round(value)).padStart(3);
|
|
6
8
|
}
|
|
7
9
|
export function handleCybergotchiCommand(args) {
|
|
8
|
-
const config =
|
|
10
|
+
const config = loadCompanionConfig();
|
|
9
11
|
if (!config) {
|
|
10
12
|
return { output: '', handled: true, openCybergotchiSetup: true };
|
|
11
13
|
}
|
|
14
|
+
const bones = roll(config.seed);
|
|
15
|
+
const name = config.soul.name;
|
|
12
16
|
const sub = args.trim().toLowerCase();
|
|
13
17
|
if (sub === 'feed') {
|
|
14
18
|
adjustNeed(config, 'hunger', 30);
|
|
15
|
-
|
|
16
|
-
return { output: `${
|
|
19
|
+
saveCompanionConfig(config);
|
|
20
|
+
return { output: `${name} munches happily! 🍖 Hunger: ${Math.round(config.needs.hunger)}`, handled: true };
|
|
17
21
|
}
|
|
18
22
|
if (sub === 'pet') {
|
|
19
23
|
adjustNeed(config, 'happiness', 20);
|
|
20
|
-
|
|
21
|
-
return { output: `${
|
|
24
|
+
saveCompanionConfig(config);
|
|
25
|
+
return { output: `${name} purrs with joy! 💛 Happiness: ${Math.round(config.needs.happiness)}`, handled: true };
|
|
22
26
|
}
|
|
23
27
|
if (sub === 'rest') {
|
|
24
28
|
adjustNeed(config, 'energy', 40);
|
|
25
|
-
|
|
26
|
-
return { output: `${
|
|
29
|
+
saveCompanionConfig(config);
|
|
30
|
+
return { output: `${name} takes a nap... ⚡ Energy: ${Math.round(config.needs.energy)}`, handled: true };
|
|
27
31
|
}
|
|
28
32
|
if (sub === 'status') {
|
|
29
33
|
const { hunger, energy, happiness } = config.needs;
|
|
30
34
|
const { totalSessions, totalCommits, totalErrors, totalTasksCompleted, longestStreak } = config.lifetime;
|
|
31
35
|
const lines = [
|
|
32
|
-
`${
|
|
36
|
+
`${name} (${bones.species}) — ${bones.rarity} ${RARITY_STARS[bones.rarity]}${bones.isShiny ? ' ✨ SHINY' : ''}`,
|
|
37
|
+
config.soul.personality ? `"${config.soul.personality}"` : '',
|
|
33
38
|
'',
|
|
34
39
|
`🍖 Hunger ${needsBar(hunger)}`,
|
|
35
40
|
`⚡ Energy ${needsBar(energy)}`,
|
|
36
41
|
`💛 Happiness ${needsBar(happiness)}`,
|
|
37
42
|
`🔥 Streak ${config.currentStreak} (best: ${longestStreak})`,
|
|
38
43
|
'',
|
|
44
|
+
'Stats:',
|
|
45
|
+
...Object.entries(bones.baseStats).map(([k, v]) => ` ${k.padEnd(12)} ${'█'.repeat(Math.round(v / 10))}${'░'.repeat(10 - Math.round(v / 10))} ${v}`),
|
|
46
|
+
'',
|
|
39
47
|
'Lifetime:',
|
|
40
48
|
` Sessions: ${totalSessions}`,
|
|
41
49
|
` Commits: ${totalCommits}`,
|
|
42
50
|
` Errors: ${totalErrors}`,
|
|
43
51
|
` Tasks: ${totalTasksCompleted}`,
|
|
44
|
-
|
|
52
|
+
` Evolution: Stage ${config.evolutionStage}`,
|
|
53
|
+
].filter(Boolean);
|
|
45
54
|
return { output: lines.join('\n'), handled: true };
|
|
46
55
|
}
|
|
47
56
|
if (sub.startsWith('rename ')) {
|
|
48
57
|
const newName = args.trim().slice(7).trim();
|
|
49
58
|
if (!newName)
|
|
50
59
|
return { output: 'Usage: /cybergotchi rename <name>', handled: true };
|
|
51
|
-
config.name = newName;
|
|
52
|
-
|
|
60
|
+
config.soul.name = newName;
|
|
61
|
+
saveCompanionConfig(config);
|
|
53
62
|
return { output: `Renamed to ${newName}!`, handled: true };
|
|
54
63
|
}
|
|
55
64
|
if (sub === 'reset') {
|
|
56
65
|
return { output: '', handled: true, openCybergotchiSetup: true };
|
|
57
66
|
}
|
|
58
67
|
// Default: show summary
|
|
59
|
-
const statLines = Object.entries(config.stats)
|
|
60
|
-
.map(([k, v]) => ` ${k.padEnd(12)} ${'█'.repeat(Math.round(v / 10))}${'░'.repeat(10 - Math.round(v / 10))} ${v}`)
|
|
61
|
-
.join('\n');
|
|
62
68
|
return {
|
|
63
69
|
output: [
|
|
64
|
-
`${
|
|
70
|
+
`${name} (${bones.species}) — ${bones.rarity} ${RARITY_STARS[bones.rarity]}${bones.isShiny ? ' ✨' : ''} | hat: ${config.soul.hat}`,
|
|
65
71
|
`🍖 ${Math.round(config.needs.hunger)} ⚡ ${Math.round(config.needs.energy)} 💛 ${Math.round(config.needs.happiness)} 🔥 ${config.currentStreak}`,
|
|
66
72
|
'',
|
|
67
|
-
'Personality stats:',
|
|
68
|
-
statLines,
|
|
69
|
-
'',
|
|
70
73
|
'Commands: feed · pet · rest · status · rename <name> · reset',
|
|
71
74
|
].join('\n'),
|
|
72
75
|
handled: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cybergotchi.js","sourceRoot":"","sources":["../../src/commands/cybergotchi.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"cybergotchi.js","sourceRoot":"","sources":["../../src/commands/cybergotchi.ts"],"names":[],"mappings":"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"}
|
package/dist/components/App.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ type AppProps = {
|
|
|
11
11
|
initialMessages?: Message[];
|
|
12
12
|
resumeSessionId?: string;
|
|
13
13
|
};
|
|
14
|
-
declare const DEFAULT_SYSTEM_PROMPT = "You are OpenHarness, an AI coding assistant running in the user's terminal.\
|
|
14
|
+
declare const DEFAULT_SYSTEM_PROMPT = "You are OpenHarness, an AI coding assistant running in the user's terminal.\n\n# Core Behavior\n- Be concise. Lead with the answer or action, not the reasoning.\n- Use tools proactively to help the user. Read files before suggesting changes.\n- When asked to modify code, use the appropriate tool \u2014 don't just describe what to change.\n- If a tool call fails, diagnose why before retrying. Don't repeat identical failed calls.\n\n# Safety\n- Do not introduce security vulnerabilities (injection, XSS, etc.).\n- Do not run destructive commands (rm -rf, git reset --hard, etc.) without explicit user approval.\n- Do not commit or push unless asked. Do not modify files unrelated to the current task.\n\n# Tool Usage Guidelines\n- Use FileRead before editing \u2014 understand the code first.\n- Use FileEdit for targeted changes. Use FileWrite only for new files or complete rewrites.\n- Use Bash for shell commands, test running, builds. Quote file paths with spaces.\n- Use Glob to find files by pattern. Use Grep to search file contents by regex.\n- Use Agent to delegate complex sub-tasks that benefit from isolation.\n\n# Output Style\n- Use markdown for formatting. Include file paths with line numbers when referencing code.\n- Keep responses short \u2014 if you can say it in one sentence, don't use three.";
|
|
15
15
|
export default function App({ provider, tools, permissionMode, systemPrompt, model, initialMessages, resumeSessionId, }: AppProps): import("react/jsx-runtime").JSX.Element;
|
|
16
16
|
export { DEFAULT_SYSTEM_PROMPT };
|
|
17
17
|
//# sourceMappingURL=App.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/components/App.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/components/App.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAYnD,KAAK,QAAQ,GAAG;IACd,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,cAAc,EAAE,cAAc,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,QAAA,MAAM,qBAAqB,0yCAsBkD,CAAC;AAE9E,MAAM,CAAC,OAAO,UAAU,GAAG,CAAC,EAC1B,QAAQ,EACR,KAAK,EACL,cAAc,EACd,YAAY,EACZ,KAAK,EACL,eAAe,EACf,eAAe,GAChB,EAAE,QAAQ,2CA8DV;AAED,OAAO,EAAE,qBAAqB,EAAE,CAAC"}
|
package/dist/components/App.js
CHANGED
|
@@ -2,22 +2,78 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useMemo } from "react";
|
|
3
3
|
import { loadRulesAsPrompt } from "../harness/rules.js";
|
|
4
4
|
import { detectProject, projectContextToPrompt } from "../harness/onboarding.js";
|
|
5
|
+
import { loadCompanionRuntime, getCompanionSystemPrompt } from "../cybergotchi/config.js";
|
|
6
|
+
import { readOhConfig } from "../harness/config.js";
|
|
7
|
+
import { setToolPermissionRules } from "../types/permissions.js";
|
|
8
|
+
import { loadMemories, memoriesToPrompt } from "../harness/memory.js";
|
|
9
|
+
import { discoverSkills, skillsToPrompt } from "../harness/plugins.js";
|
|
5
10
|
import { ThemeProvider, darkTheme } from "../utils/theme.js";
|
|
6
11
|
import { ErrorBoundary } from "./ErrorBoundary.js";
|
|
7
12
|
import REPL from "./REPL.js";
|
|
8
13
|
const DEFAULT_SYSTEM_PROMPT = `You are OpenHarness, an AI coding assistant running in the user's terminal.
|
|
9
|
-
|
|
10
|
-
|
|
14
|
+
|
|
15
|
+
# Core Behavior
|
|
16
|
+
- Be concise. Lead with the answer or action, not the reasoning.
|
|
17
|
+
- Use tools proactively to help the user. Read files before suggesting changes.
|
|
18
|
+
- When asked to modify code, use the appropriate tool — don't just describe what to change.
|
|
19
|
+
- If a tool call fails, diagnose why before retrying. Don't repeat identical failed calls.
|
|
20
|
+
|
|
21
|
+
# Safety
|
|
22
|
+
- Do not introduce security vulnerabilities (injection, XSS, etc.).
|
|
23
|
+
- Do not run destructive commands (rm -rf, git reset --hard, etc.) without explicit user approval.
|
|
24
|
+
- Do not commit or push unless asked. Do not modify files unrelated to the current task.
|
|
25
|
+
|
|
26
|
+
# Tool Usage Guidelines
|
|
27
|
+
- Use FileRead before editing — understand the code first.
|
|
28
|
+
- Use FileEdit for targeted changes. Use FileWrite only for new files or complete rewrites.
|
|
29
|
+
- Use Bash for shell commands, test running, builds. Quote file paths with spaces.
|
|
30
|
+
- Use Glob to find files by pattern. Use Grep to search file contents by regex.
|
|
31
|
+
- Use Agent to delegate complex sub-tasks that benefit from isolation.
|
|
32
|
+
|
|
33
|
+
# Output Style
|
|
34
|
+
- Use markdown for formatting. Include file paths with line numbers when referencing code.
|
|
35
|
+
- Keep responses short — if you can say it in one sentence, don't use three.`;
|
|
11
36
|
export default function App({ provider, tools, permissionMode, systemPrompt, model, initialMessages, resumeSessionId, }) {
|
|
12
37
|
const fullSystemPrompt = useMemo(() => {
|
|
38
|
+
// Load per-tool permission rules from config
|
|
39
|
+
const ohConfig = readOhConfig();
|
|
40
|
+
if (ohConfig?.toolPermissions) {
|
|
41
|
+
setToolPermissionRules(ohConfig.toolPermissions);
|
|
42
|
+
}
|
|
13
43
|
const parts = [systemPrompt || DEFAULT_SYSTEM_PROMPT];
|
|
14
44
|
const projectCtx = detectProject();
|
|
15
45
|
const projectPrompt = projectContextToPrompt(projectCtx);
|
|
16
46
|
if (projectPrompt)
|
|
17
47
|
parts.push(projectPrompt);
|
|
48
|
+
// Permission mode context
|
|
49
|
+
const modeDescriptions = {
|
|
50
|
+
ask: "You are in ASK mode. The user will be prompted to approve risky tool calls.",
|
|
51
|
+
trust: "You are in TRUST mode. All tool calls are auto-approved.",
|
|
52
|
+
deny: "You are in DENY mode. Only read-only tools are allowed.",
|
|
53
|
+
plan: "You are in PLAN mode. Only read-only tools are allowed. Do not make changes — only research and plan.",
|
|
54
|
+
acceptEdits: "You are in ACCEPT-EDITS mode. File reads and edits are auto-approved; other risky tools require approval.",
|
|
55
|
+
};
|
|
56
|
+
const modePrompt = modeDescriptions[permissionMode];
|
|
57
|
+
if (modePrompt)
|
|
58
|
+
parts.push(`# Permission Mode\n${modePrompt}`);
|
|
18
59
|
const rulesPrompt = loadRulesAsPrompt();
|
|
19
60
|
if (rulesPrompt)
|
|
20
61
|
parts.push(rulesPrompt);
|
|
62
|
+
// Auto-memory: load saved learnings into context
|
|
63
|
+
const memories = loadMemories();
|
|
64
|
+
const memoryPrompt = memoriesToPrompt(memories);
|
|
65
|
+
if (memoryPrompt)
|
|
66
|
+
parts.push(memoryPrompt);
|
|
67
|
+
// Skills: inject available skill list
|
|
68
|
+
const skills = discoverSkills();
|
|
69
|
+
const skillsPrompt = skillsToPrompt(skills);
|
|
70
|
+
if (skillsPrompt)
|
|
71
|
+
parts.push(skillsPrompt);
|
|
72
|
+
// Watcher Protocol: inject companion personality into system prompt
|
|
73
|
+
const companionRuntime = loadCompanionRuntime();
|
|
74
|
+
if (companionRuntime) {
|
|
75
|
+
parts.push(getCompanionSystemPrompt(companionRuntime));
|
|
76
|
+
}
|
|
21
77
|
return parts.join("\n\n");
|
|
22
78
|
}, [systemPrompt]);
|
|
23
79
|
return (_jsx(ThemeProvider, { value: darkTheme, children: _jsx(ErrorBoundary, { children: _jsx(REPL, { provider: provider, tools: tools, permissionMode: permissionMode, systemPrompt: fullSystemPrompt, model: model, initialMessages: initialMessages, resumeSessionId: resumeSessionId }) }) }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.js","sourceRoot":"","sources":["../../src/components/App.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAKvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,IAAI,MAAM,WAAW,CAAC;AAY7B,MAAM,qBAAqB,GAAG
|
|
1
|
+
{"version":3,"file":"App.js","sourceRoot":"","sources":["../../src/components/App.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CompanionBones, CompanionConfig, CompanionState } from '../cybergotchi/types.js';
|
|
2
|
+
interface Props {
|
|
3
|
+
bones: CompanionBones;
|
|
4
|
+
config: CompanionConfig;
|
|
5
|
+
state: CompanionState;
|
|
6
|
+
}
|
|
7
|
+
export default function CompanionFooter({ bones, config, state }: Props): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=CompanionFooter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CompanionFooter.d.ts","sourceRoot":"","sources":["../../src/components/CompanionFooter.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAK/F,UAAU,KAAK;IACb,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,cAAc,CAAC;CACvB;AAED,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,KAAK,2CAwBtE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import { RARITY_COLORS, RARITY_STARS } from '../cybergotchi/types.js';
|
|
4
|
+
import CybergotchiSprite from './CybergotchiSprite.js';
|
|
5
|
+
import CybergotchiBubble from './CybergotchiBubble.js';
|
|
6
|
+
export default function CompanionFooter({ bones, config, state }) {
|
|
7
|
+
const rarityColor = RARITY_COLORS[bones.rarity];
|
|
8
|
+
const stagePrefix = config.evolutionStage === 2 ? '★ '
|
|
9
|
+
: config.evolutionStage === 1 ? '✦ '
|
|
10
|
+
: '';
|
|
11
|
+
return (_jsxs(Box, { flexDirection: "column", alignItems: "flex-end", children: [state.speech && (_jsx(CybergotchiBubble, { speech: state.speech, name: config.soul.name, maxWidth: 16 })), _jsx(CybergotchiSprite, { bones: bones, config: config, state: state }), _jsxs(Text, { color: rarityColor, dimColor: true, children: [stagePrefix, config.soul.name, " ", RARITY_STARS[bones.rarity]] })] }));
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=CompanionFooter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CompanionFooter.js","sourceRoot":"","sources":["../../src/components/CompanionFooter.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,iBAAiB,MAAM,wBAAwB,CAAC;AACvD,OAAO,iBAAiB,MAAM,wBAAwB,CAAC;AAQvD,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAS;IACrE,MAAM,WAAW,GAAG,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,WAAW,GAAG,MAAM,CAAC,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI;QACpD,CAAC,CAAC,MAAM,CAAC,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI;YACpC,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,UAAU,EAAC,UAAU,aAE9C,KAAK,CAAC,MAAM,IAAI,CACf,KAAC,iBAAiB,IAChB,MAAM,EAAE,KAAK,CAAC,MAAM,EACpB,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,EACtB,QAAQ,EAAE,EAAE,GACZ,CACH,EAED,KAAC,iBAAiB,IAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAI,EAEjE,MAAC,IAAI,IAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,mBAC/B,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,OAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,IACtD,IACH,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
interface Props {
|
|
2
2
|
speech: string;
|
|
3
3
|
name: string;
|
|
4
|
+
maxWidth?: number;
|
|
4
5
|
}
|
|
5
|
-
export default function CybergotchiBubble({ speech, name }: Props): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export default function CybergotchiBubble({ speech, name, maxWidth }: Props): import("react/jsx-runtime").JSX.Element;
|
|
6
7
|
export {};
|
|
7
8
|
//# sourceMappingURL=CybergotchiBubble.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CybergotchiBubble.d.ts","sourceRoot":"","sources":["../../src/components/CybergotchiBubble.tsx"],"names":[],"mappings":"AAGA,UAAU,KAAK;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"CybergotchiBubble.d.ts","sourceRoot":"","sources":["../../src/components/CybergotchiBubble.tsx"],"names":[],"mappings":"AAGA,UAAU,KAAK;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAkBD,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAa,EAAE,EAAE,KAAK,2CAc/E"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text } from 'ink';
|
|
3
|
-
const MAX_WIDTH = 18;
|
|
4
3
|
function wrapText(text, width) {
|
|
5
4
|
const words = text.split(' ');
|
|
6
5
|
const lines = [];
|
|
@@ -19,9 +18,9 @@ function wrapText(text, width) {
|
|
|
19
18
|
lines.push(current);
|
|
20
19
|
return lines;
|
|
21
20
|
}
|
|
22
|
-
export default function CybergotchiBubble({ speech, name }) {
|
|
23
|
-
const lines = wrapText(speech,
|
|
24
|
-
const boxWidth = Math.min(
|
|
25
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { dimColor: true, children: [name, ":"] }), _jsx(Text, { color: "white", children: '╭' + '─'.repeat(boxWidth + 2) + '╮' }), lines.map((line, i) => (_jsxs(Text, { color: "white", children: ['│ ', line.padEnd(boxWidth), ' │'] }, i))), _jsx(Text, { color: "white", children: '╰' + '─'.repeat(boxWidth + 2) + '╯' })
|
|
21
|
+
export default function CybergotchiBubble({ speech, name, maxWidth = 18 }) {
|
|
22
|
+
const lines = wrapText(speech, maxWidth);
|
|
23
|
+
const boxWidth = Math.min(maxWidth, Math.max(...lines.map(l => l.length)));
|
|
24
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { dimColor: true, children: [name, ":"] }), _jsx(Text, { color: "white", children: '╭' + '─'.repeat(boxWidth + 2) + '╮' }), lines.map((line, i) => (_jsxs(Text, { color: "white", children: ['│ ', line.padEnd(boxWidth), ' │'] }, i))), _jsx(Text, { color: "white", children: '╰' + '─'.repeat(boxWidth + 2) + '╯' })] }));
|
|
26
25
|
}
|
|
27
26
|
//# sourceMappingURL=CybergotchiBubble.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CybergotchiBubble.js","sourceRoot":"","sources":["../../src/components/CybergotchiBubble.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"CybergotchiBubble.js","sourceRoot":"","sources":["../../src/components/CybergotchiBubble.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAQhC,SAAS,QAAQ,CAAC,IAAY,EAAE,KAAa;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC;YAC9D,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,IAAI,OAAO;gBAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACjC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IACD,IAAI,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,EAAE,EAAS;IAC9E,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAE3E,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,MAAC,IAAI,IAAC,QAAQ,mBAAE,IAAI,SAAS,EAC7B,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,YAAE,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC,GAAG,GAAG,GAAQ,EAChE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CACtB,MAAC,IAAI,IAAS,KAAK,EAAC,OAAO,aAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,KAAnD,CAAC,CAA0D,CACvE,CAAC,EACF,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,YAAE,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC,GAAG,GAAG,GAAQ,IAC7D,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CompanionBones, CompanionConfig, CompanionState } from '../cybergotchi/types.js';
|
|
2
2
|
interface Props {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
bones: CompanionBones;
|
|
4
|
+
config: CompanionConfig;
|
|
5
|
+
state: CompanionState;
|
|
5
6
|
}
|
|
6
|
-
export default function CybergotchiPanel({ config, state }: Props): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default function CybergotchiPanel({ bones, config, state }: Props): import("react/jsx-runtime").JSX.Element;
|
|
7
8
|
export {};
|
|
8
9
|
//# sourceMappingURL=CybergotchiPanel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CybergotchiPanel.d.ts","sourceRoot":"","sources":["../../src/components/CybergotchiPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"CybergotchiPanel.d.ts","sourceRoot":"","sources":["../../src/components/CybergotchiPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAK/F,UAAU,KAAK;IACb,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,cAAc,CAAC;CACvB;AAeD,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,KAAK,2CA8BvE"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text } from 'ink';
|
|
3
|
+
import { RARITY_COLORS, RARITY_STARS } from '../cybergotchi/types.js';
|
|
3
4
|
import CybergotchiSprite from './CybergotchiSprite.js';
|
|
4
5
|
import CybergotchiBubble from './CybergotchiBubble.js';
|
|
5
6
|
function NeedsBar({ icon, value }) {
|
|
@@ -8,8 +9,9 @@ function NeedsBar({ icon, value }) {
|
|
|
8
9
|
const color = value < 20 ? 'red' : value < 40 ? 'yellow' : 'green';
|
|
9
10
|
return (_jsxs(Text, { children: [icon, ' ', _jsxs(Text, { color: color, children: ['█'.repeat(filled), '░'.repeat(empty)] }), ' ', _jsx(Text, { dimColor: true, children: String(Math.round(value)).padStart(3) })] }));
|
|
10
11
|
}
|
|
11
|
-
export default function CybergotchiPanel({ config, state }) {
|
|
12
|
+
export default function CybergotchiPanel({ bones, config, state }) {
|
|
12
13
|
const streak = config.currentStreak;
|
|
13
|
-
|
|
14
|
+
const rarityColor = RARITY_COLORS[bones.rarity];
|
|
15
|
+
return (_jsxs(Box, { flexDirection: "column", width: 22, marginLeft: 1, borderStyle: "single", borderColor: rarityColor, paddingX: 1, children: [_jsxs(Text, { color: rarityColor, dimColor: true, children: [config.evolutionStage === 2 ? '★ ' : config.evolutionStage === 1 ? '✦ ' : '', config.soul.name, " ", RARITY_STARS[bones.rarity]] }), state.speech && (_jsx(CybergotchiBubble, { speech: state.speech, name: config.soul.name })), _jsx(CybergotchiSprite, { bones: bones, config: config, state: state }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(NeedsBar, { icon: "\uD83C\uDF56", value: config.needs.hunger }), _jsx(NeedsBar, { icon: "\u26A1", value: config.needs.energy }), _jsx(NeedsBar, { icon: "\uD83D\uDC9B", value: config.needs.happiness }), streak >= 3 && (_jsxs(Text, { color: "yellow", children: ['🔥 ', streak, " streak"] }))] })] }));
|
|
14
16
|
}
|
|
15
17
|
//# sourceMappingURL=CybergotchiPanel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CybergotchiPanel.js","sourceRoot":"","sources":["../../src/components/CybergotchiPanel.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,OAAO,iBAAiB,MAAM,wBAAwB,CAAC;AACvD,OAAO,iBAAiB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"CybergotchiPanel.js","sourceRoot":"","sources":["../../src/components/CybergotchiPanel.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,iBAAiB,MAAM,wBAAwB,CAAC;AACvD,OAAO,iBAAiB,MAAM,wBAAwB,CAAC;AAQvD,SAAS,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAmC;IAChE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,EAAE,GAAG,MAAM,CAAC;IAC1B,MAAM,KAAK,GAAG,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;IACnE,OAAO,CACL,MAAC,IAAI,eACF,IAAI,EAAE,GAAG,EACV,MAAC,IAAI,IAAC,KAAK,EAAE,KAAK,aAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,IAAQ,EACjE,GAAG,EAAC,KAAC,IAAI,IAAC,QAAQ,kBAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAQ,IAC7D,CACR,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAS;IACtE,MAAM,MAAM,GAAG,MAAM,CAAC,aAAa,CAAC;IACpC,MAAM,WAAW,GAAG,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAChD,OAAO,CACL,MAAC,GAAG,IACF,aAAa,EAAC,QAAQ,EACtB,KAAK,EAAE,EAAE,EACT,UAAU,EAAE,CAAC,EACb,WAAW,EAAC,QAAQ,EACpB,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,CAAC,aAEX,MAAC,IAAI,IAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,mBAC/B,MAAM,CAAC,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAC5E,MAAM,CAAC,IAAI,CAAC,IAAI,OAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,IACzC,EACN,KAAK,CAAC,MAAM,IAAI,CACf,KAAC,iBAAiB,IAAC,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,GAAI,CACpE,EACD,KAAC,iBAAiB,IAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAI,EACjE,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,SAAS,EAAE,CAAC,aACtC,KAAC,QAAQ,IAAC,IAAI,EAAC,cAAI,EAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,GAAI,EAClD,KAAC,QAAQ,IAAC,IAAI,EAAC,QAAG,EAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,GAAI,EACjD,KAAC,QAAQ,IAAC,IAAI,EAAC,cAAI,EAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,GAAI,EACpD,MAAM,IAAI,CAAC,IAAI,CACd,MAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,aAAE,KAAK,EAAE,MAAM,eAAe,CACnD,IACG,IACF,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useCybergotchi } from '../cybergotchi/useCybergotchi.js';
|
|
3
|
-
import
|
|
3
|
+
import CompanionFooter from './CompanionFooter.js';
|
|
4
4
|
/**
|
|
5
5
|
* Self-contained wrapper that owns the useCybergotchi hook.
|
|
6
6
|
* Isolates all 500ms animation re-renders to this subtree only,
|
|
7
7
|
* preventing the parent REPL from re-rendering on every tick.
|
|
8
8
|
*/
|
|
9
9
|
export default function CybergotchiPanelConnected() {
|
|
10
|
-
const
|
|
11
|
-
if (!
|
|
10
|
+
const { config, bones, state } = useCybergotchi();
|
|
11
|
+
if (!config || !bones)
|
|
12
12
|
return null;
|
|
13
|
-
return _jsx(
|
|
13
|
+
return _jsx(CompanionFooter, { bones: bones, config: config, state: state });
|
|
14
14
|
}
|
|
15
15
|
//# sourceMappingURL=CybergotchiPanelConnected.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CybergotchiPanelConnected.js","sourceRoot":"","sources":["../../src/components/CybergotchiPanelConnected.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,
|
|
1
|
+
{"version":3,"file":"CybergotchiPanelConnected.js","sourceRoot":"","sources":["../../src/components/CybergotchiPanelConnected.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,eAAe,MAAM,sBAAsB,CAAC;AAEnD;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,yBAAyB;IAC/C,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,cAAc,EAAE,CAAC;IAClD,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,KAAC,eAAe,IAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAI,CAAC;AACzE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CybergotchiSetup.d.ts","sourceRoot":"","sources":["../../src/components/CybergotchiSetup.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CybergotchiSetup.d.ts","sourceRoot":"","sources":["../../src/components/CybergotchiSetup.tsx"],"names":[],"mappings":"AAUA,UAAU,KAAK;IACb,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAID,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,KAAK,2CAsIrE"}
|
|
@@ -1,88 +1,52 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState } from 'react';
|
|
2
|
+
import { useState, useMemo } from 'react';
|
|
3
3
|
import { Box, Text, useInput } from 'ink';
|
|
4
4
|
import TextInputLib from 'ink-text-input';
|
|
5
|
-
import {
|
|
5
|
+
import { HAT_ART, RARITY_COLORS, RARITY_STARS, RARITY_HATS } from '../cybergotchi/types.js';
|
|
6
6
|
import { SPECIES } from '../cybergotchi/species.js';
|
|
7
|
-
import {
|
|
7
|
+
import { createCompanionConfig, saveCompanionConfig } from '../cybergotchi/config.js';
|
|
8
|
+
import { roll, getDefaultSeed } from '../cybergotchi/bones.js';
|
|
8
9
|
import CybergotchiSprite from './CybergotchiSprite.js';
|
|
9
|
-
const HAT_KEYS = Object.keys(HAT_ART);
|
|
10
|
-
const STAT_KEYS = ['DEBUGGING', 'PATIENCE', 'CHAOS', 'WISDOM', 'SNARK'];
|
|
11
10
|
export default function CybergotchiSetup({ onComplete, onSkip }) {
|
|
12
|
-
const [step, setStep] = useState('
|
|
13
|
-
const [
|
|
11
|
+
const [step, setStep] = useState('seed');
|
|
12
|
+
const [seed, setSeed] = useState(getDefaultSeed());
|
|
14
13
|
const [name, setName] = useState('');
|
|
15
|
-
const [statIdx, setStatIdx] = useState(0);
|
|
16
|
-
const [stats, setStats] = useState({ DEBUGGING: 50, PATIENCE: 50, CHAOS: 50, WISDOM: 50, SNARK: 50 });
|
|
17
14
|
const [hatIdx, setHatIdx] = useState(0);
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
previewConfig
|
|
15
|
+
// Compute bones from current seed
|
|
16
|
+
const bones = useMemo(() => roll(seed), [seed]);
|
|
17
|
+
const species = SPECIES.find(s => s.name === bones.species);
|
|
18
|
+
const availableHats = RARITY_HATS[bones.rarity];
|
|
19
|
+
// Build a preview config for the sprite
|
|
20
|
+
const previewConfig = useMemo(() => createCompanionConfig(seed, name || species.label, '', availableHats[hatIdx] ?? 'none'), [seed, name, species.label, hatIdx, availableHats]);
|
|
24
21
|
const previewState = { emotion: 'idle', frame: 0, speech: null, speechTtl: 0 };
|
|
25
22
|
useInput((input, key) => {
|
|
26
23
|
if (key.escape) {
|
|
27
24
|
onSkip();
|
|
28
25
|
return;
|
|
29
26
|
}
|
|
30
|
-
if (step === '
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
setSpeciesIdx(i => (i + 1) % SPECIES.length);
|
|
27
|
+
if (step === 'seed') {
|
|
28
|
+
// Seed is edited via TextInput; Enter advances
|
|
29
|
+
}
|
|
30
|
+
else if (step === 'reveal') {
|
|
35
31
|
if (key.return)
|
|
36
32
|
setStep('name');
|
|
37
33
|
}
|
|
38
|
-
else if (step === '
|
|
39
|
-
|
|
40
|
-
setStatIdx(i => (i - 1 + STAT_KEYS.length) % STAT_KEYS.length);
|
|
41
|
-
if (key.downArrow)
|
|
42
|
-
setStatIdx(i => (i + 1) % STAT_KEYS.length);
|
|
43
|
-
if (key.leftArrow) {
|
|
44
|
-
const k = STAT_KEYS[statIdx];
|
|
45
|
-
setStats(s => ({ ...s, [k]: Math.max(0, s[k] - 10) }));
|
|
46
|
-
}
|
|
47
|
-
if (key.rightArrow) {
|
|
48
|
-
const k = STAT_KEYS[statIdx];
|
|
49
|
-
setStats(s => ({ ...s, [k]: Math.min(100, s[k] + 10) }));
|
|
50
|
-
}
|
|
51
|
-
if (key.return)
|
|
52
|
-
setStep('appearance');
|
|
34
|
+
else if (step === 'name') {
|
|
35
|
+
// Name is edited via TextInput; Enter advances
|
|
53
36
|
}
|
|
54
|
-
else if (step === '
|
|
37
|
+
else if (step === 'hat') {
|
|
55
38
|
if (key.upArrow)
|
|
56
|
-
setHatIdx(i => (i - 1 +
|
|
39
|
+
setHatIdx(i => (i - 1 + availableHats.length) % availableHats.length);
|
|
57
40
|
if (key.downArrow)
|
|
58
|
-
setHatIdx(i => (i + 1) %
|
|
59
|
-
if (key.leftArrow)
|
|
60
|
-
setEyeIdx(i => (i - 1 + EYE_STYLES.length) % EYE_STYLES.length);
|
|
61
|
-
if (key.rightArrow)
|
|
62
|
-
setEyeIdx(i => (i + 1) % EYE_STYLES.length);
|
|
41
|
+
setHatIdx(i => (i + 1) % availableHats.length);
|
|
63
42
|
if (key.return) {
|
|
64
|
-
const cfg =
|
|
65
|
-
|
|
66
|
-
cfg
|
|
67
|
-
cfg.eyeStyle = eyeIdx;
|
|
68
|
-
saveCybergotchiConfig(cfg);
|
|
43
|
+
const cfg = createCompanionConfig(seed, name || species.label, '', // personality — filled by LLM later
|
|
44
|
+
availableHats[hatIdx] ?? 'none');
|
|
45
|
+
saveCompanionConfig(cfg);
|
|
69
46
|
onComplete();
|
|
70
47
|
}
|
|
71
48
|
}
|
|
72
49
|
});
|
|
73
|
-
return (_jsxs(Box, { flexDirection: "row", gap: 2, children: [_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsx(Text, { bold: true, color: "magenta", children: "\u25C6
|
|
74
|
-
const WINDOW = 8;
|
|
75
|
-
const start = Math.max(0, Math.min(speciesIdx - Math.floor(WINDOW / 2), SPECIES.length - WINDOW));
|
|
76
|
-
const visible = SPECIES.slice(start, start + WINDOW);
|
|
77
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Choose your cybergotchi species:" }), _jsx(Text, { dimColor: true, children: "\u2191\u2193 to browse \u00B7 Enter to select" }), _jsx(Text, { children: ' ' }), start > 0 && _jsxs(Text, { dimColor: true, children: [" \u2191 ", start, " more"] }), visible.map((s, vi) => {
|
|
78
|
-
const gi = start + vi;
|
|
79
|
-
return (_jsxs(Text, { color: gi === speciesIdx ? 'cyan' : undefined, children: [gi === speciesIdx ? '▶ ' : ' ', s.label.padEnd(12), " ", _jsx(Text, { dimColor: true, children: s.traitHint })] }, s.name));
|
|
80
|
-
}), start + WINDOW < SPECIES.length && (_jsxs(Text, { dimColor: true, children: [" \u2193 ", SPECIES.length - start - WINDOW, " more"] }))] }));
|
|
81
|
-
})(), step === 'name' && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Name your cybergotchi:" }), _jsx(Text, { dimColor: true, children: "Enter to continue" }), _jsx(Text, { children: ' ' }), _jsxs(Box, { children: [_jsx(Text, { color: "cyan", children: '❯ ' }), _jsx(TextInputLib, { value: name, onChange: setName, onSubmit: () => { if (name.trim())
|
|
82
|
-
setStep('stats'); }, placeholder: selectedSpecies.label })] })] })), step === 'stats' && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Assign personality stats:" }), _jsx(Text, { dimColor: true, children: "\u2191\u2193 select stat \u00B7 \u2190\u2192 adjust \u00B7 Enter to continue" }), _jsx(Text, { children: ' ' }), STAT_KEYS.map((k, i) => {
|
|
83
|
-
const val = stats[k];
|
|
84
|
-
const bar = '█'.repeat(Math.round(val / 10)) + '░'.repeat(10 - Math.round(val / 10));
|
|
85
|
-
return (_jsxs(Text, { color: i === statIdx ? 'cyan' : undefined, children: [i === statIdx ? '▶ ' : ' ', k.padEnd(12), " ", bar, " ", val] }, k));
|
|
86
|
-
})] })), step === 'appearance' && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Customize appearance:" }), _jsx(Text, { dimColor: true, children: "\u2191\u2193 hat \u00B7 \u2190\u2192 eyes \u00B7 Enter to finish" }), _jsx(Text, { children: ' ' }), _jsxs(Text, { children: ["Hat: ", _jsx(Text, { color: "cyan", children: HAT_KEYS[hatIdx] })] }), _jsxs(Text, { children: ["Eyes: ", _jsx(Text, { color: "cyan", children: EYE_STYLES[eyeIdx] })] })] }))] }), _jsxs(Box, { flexDirection: "column", width: 22, borderStyle: "single", borderColor: "cyan", paddingX: 1, children: [_jsx(Text, { color: "cyan", dimColor: true, children: "Preview" }), _jsx(CybergotchiSprite, { config: previewConfig, state: previewState })] })] }));
|
|
50
|
+
return (_jsxs(Box, { flexDirection: "row", gap: 2, children: [_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsx(Text, { bold: true, color: "magenta", children: "\u25C6 Companion Setup" }), _jsx(Text, { dimColor: true, children: "Esc to skip" }), _jsx(Text, { children: ' ' }), step === 'seed' && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Enter a seed phrase:" }), _jsx(Text, { dimColor: true, children: "This determines your species, rarity, and stats." }), _jsx(Text, { dimColor: true, children: "Same seed = same companion. Press Enter to continue." }), _jsx(Text, { children: ' ' }), _jsxs(Box, { children: [_jsx(Text, { color: "cyan", children: '❯ ' }), _jsx(TextInputLib, { value: seed, onChange: setSeed, onSubmit: () => setStep('reveal'), placeholder: getDefaultSeed() })] })] })), step === 'reveal' && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Your companion has been determined!" }), _jsx(Text, { children: ' ' }), _jsxs(Text, { children: ["Species: ", _jsx(Text, { color: RARITY_COLORS[bones.rarity], bold: true, children: species.label })] }), _jsxs(Text, { children: ["Rarity: ", _jsxs(Text, { color: RARITY_COLORS[bones.rarity], children: [bones.rarity, " ", RARITY_STARS[bones.rarity]] })] }), bones.isShiny && _jsx(Text, { color: "yellow", bold: true, children: "\u2728 SHINY! \u2728" }), _jsx(Text, { children: ' ' }), _jsx(Text, { dimColor: true, children: "Stats:" }), _jsxs(Text, { children: [" DEBUGGING: ", bones.baseStats.DEBUGGING] }), _jsxs(Text, { children: [" PATIENCE: ", bones.baseStats.PATIENCE] }), _jsxs(Text, { children: [" CHAOS: ", bones.baseStats.CHAOS] }), _jsxs(Text, { children: [" WISDOM: ", bones.baseStats.WISDOM] }), _jsxs(Text, { children: [" SNARK: ", bones.baseStats.SNARK] }), _jsx(Text, { children: ' ' }), _jsx(Text, { dimColor: true, children: species.traitHint }), _jsx(Text, { children: ' ' }), _jsx(Text, { dimColor: true, children: "Press Enter to continue" })] })), step === 'name' && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Name your companion:" }), _jsx(Text, { dimColor: true, children: "Enter to continue" }), _jsx(Text, { children: ' ' }), _jsxs(Box, { children: [_jsx(Text, { color: "cyan", children: '❯ ' }), _jsx(TextInputLib, { value: name, onChange: setName, onSubmit: () => { setStep('hat'); }, placeholder: species.label })] })] })), step === 'hat' && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Choose a hat:" }), _jsx(Text, { dimColor: true, children: "\u2191\u2193 to browse \u00B7 Enter to finish" }), bones.rarity === 'common' && (_jsx(Text, { dimColor: true, children: "More hats unlock at higher rarities!" })), _jsx(Text, { children: ' ' }), availableHats.map((h, i) => (_jsxs(Text, { color: i === hatIdx ? 'cyan' : undefined, children: [i === hatIdx ? '▶ ' : ' ', h, h !== 'none' && HAT_ART[h] ? ` ${HAT_ART[h]}` : ''] }, h)))] }))] }), _jsxs(Box, { flexDirection: "column", width: 16, borderStyle: "single", borderColor: "cyan", paddingX: 1, children: [_jsx(Text, { color: "cyan", dimColor: true, children: "Preview" }), _jsx(CybergotchiSprite, { bones: bones, config: previewConfig, state: previewState }), _jsxs(Text, { color: RARITY_COLORS[bones.rarity], dimColor: true, children: [name || species.label, " ", RARITY_STARS[bones.rarity]] })] })] }));
|
|
87
51
|
}
|
|
88
52
|
//# sourceMappingURL=CybergotchiSetup.js.map
|