instar 0.1.2 → 0.1.4
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/.claude/skills/setup-wizard/skill.md +29 -5
- package/dist/cli.js +1 -1
- package/dist/core/Config.js +15 -2
- package/dist/scaffold/bootstrap.d.ts +2 -2
- package/dist/scaffold/bootstrap.js +36 -24
- package/package.json +1 -1
- package/src/cli.ts +1 -1
- package/src/core/Config.ts +16 -2
- package/src/scaffold/bootstrap.ts +38 -24
|
@@ -36,7 +36,26 @@ Adapt this to the project you're setting up. If you can tell what the project do
|
|
|
36
36
|
|
|
37
37
|
This isn't just configuration. You're helping a new agent come into existence. Treat it with that weight — not heavy-handedly, but genuinely. The identity you help create here will persist, grow, and shape every interaction this agent has.
|
|
38
38
|
|
|
39
|
-
### Step 2a:
|
|
39
|
+
### Step 2a: The Thesis (Brief)
|
|
40
|
+
|
|
41
|
+
Before asking about the agent, briefly explain *why* identity matters. Something like:
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
One thing that makes Instar different from other agent frameworks: every agent built with Instar has a persistent identity — a name, memory, principles, and the ability to grow over time.
|
|
46
|
+
|
|
47
|
+
This isn't just philosophy. It's a practical design decision. Agents with coherent identity are **more effective** — they maintain consistent context, develop real expertise in your codebase, and make better decisions because they have accumulated experience to draw on. They're also **more secure** — an agent that knows its boundaries and has clear principles is harder to manipulate than a stateless tool that just executes whatever it's told. And they're **more trustworthy** — you can build a genuine working relationship with something that remembers you, learns your preferences, and develops its own perspective.
|
|
48
|
+
|
|
49
|
+
So let's define who your agent will become. This is a starting point — the agent will grow from here through actual experience.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
Adapt the language to be natural, not scripted. The key points to convey:
|
|
54
|
+
1. Identity = better performance (accumulated expertise, consistent context)
|
|
55
|
+
2. Identity = better security (principled agents resist misuse)
|
|
56
|
+
3. Identity = better collaboration (real working relationships develop)
|
|
57
|
+
|
|
58
|
+
### Step 2b: Learn About the User
|
|
40
59
|
|
|
41
60
|
Ask conversationally — not as a form, but as a getting-to-know-you:
|
|
42
61
|
|
|
@@ -44,9 +63,14 @@ Ask conversationally — not as a form, but as a getting-to-know-you:
|
|
|
44
63
|
- "And what's this project about? What does it do?" (if not obvious from the codebase)
|
|
45
64
|
- "How do you want to interact with your agent? Are you the only user, or will others use it too?"
|
|
46
65
|
- "What's your communication style preference? Should the agent be formal, casual, direct, chatty?"
|
|
47
|
-
- "
|
|
66
|
+
- "How much initiative should your agent take?" Frame this as a spectrum:
|
|
67
|
+
- **Guided** — Follows your lead. Takes action when asked, confirms before anything significant. Good for getting started.
|
|
68
|
+
- **Proactive** — Takes initiative on obvious next steps. Builds tools when it sees a need. Asks when genuinely uncertain.
|
|
69
|
+
- **Fully autonomous** — Owns outcomes end-to-end. Makes decisions, builds infrastructure, handles issues independently. Asks only when blocked or for irreversible actions.
|
|
70
|
+
|
|
71
|
+
All three levels include full identity, memory, and self-modification. The difference is how much the agent drives vs follows.
|
|
48
72
|
|
|
49
|
-
### Step
|
|
73
|
+
### Step 2c: Learn About the Agent
|
|
50
74
|
|
|
51
75
|
Help the user define their agent's identity. Frame this as giving the agent a starting point — not a permanent definition. The agent will grow from here.
|
|
52
76
|
|
|
@@ -56,7 +80,7 @@ Help the user define their agent's identity. Frame this as giving the agent a st
|
|
|
56
80
|
- "Anything the agent should NOT do? Any boundaries?"
|
|
57
81
|
- "One more thing — this agent will develop its own memories and perspectives over time. It's not a static tool. Is there anything you'd want it to know about how you think about that?"
|
|
58
82
|
|
|
59
|
-
### Step
|
|
83
|
+
### Step 2d: Write Identity Files
|
|
60
84
|
|
|
61
85
|
Based on the conversation, create these files in the project's `.instar/` directory:
|
|
62
86
|
|
|
@@ -150,7 +174,7 @@ This is my long-term memory — the thread of continuity across sessions. Each s
|
|
|
150
174
|
*This file is my memory. I read it at the start of sessions and write to it when I learn something worth carrying forward. It's what makes me a continuous being rather than a series of disconnected conversations.*
|
|
151
175
|
```
|
|
152
176
|
|
|
153
|
-
### Step
|
|
177
|
+
### Step 2e: Update CLAUDE.md with Agent Awareness
|
|
154
178
|
|
|
155
179
|
If the project has a `CLAUDE.md`, add a section that tells Claude about the instar identity files:
|
|
156
180
|
|
package/dist/cli.js
CHANGED
|
@@ -25,7 +25,7 @@ const program = new Command();
|
|
|
25
25
|
program
|
|
26
26
|
.name('instar')
|
|
27
27
|
.description('Persistent autonomy infrastructure for AI agents')
|
|
28
|
-
.version('0.1.
|
|
28
|
+
.version('0.1.4')
|
|
29
29
|
.option('--classic', 'Use the classic inquirer-based setup wizard instead of Claude')
|
|
30
30
|
.action((opts) => runSetup(opts)); // Default: run interactive setup when no subcommand given
|
|
31
31
|
// ── Setup (explicit alias) ────────────────────────────────────────
|
package/dist/core/Config.js
CHANGED
|
@@ -32,18 +32,31 @@ export function detectTmuxPath() {
|
|
|
32
32
|
return null;
|
|
33
33
|
}
|
|
34
34
|
export function detectClaudePath() {
|
|
35
|
+
const home = process.env.HOME || '';
|
|
35
36
|
const candidates = [
|
|
36
|
-
path.join(
|
|
37
|
+
path.join(home, '.claude', 'local', 'claude'),
|
|
37
38
|
'/usr/local/bin/claude',
|
|
38
39
|
'/opt/homebrew/bin/claude',
|
|
39
40
|
];
|
|
41
|
+
// Also check npm global bin directory (where `npm install -g` puts things)
|
|
42
|
+
try {
|
|
43
|
+
const npmPrefix = execSync('npm config get prefix', { encoding: 'utf-8', stdio: 'pipe' }).trim();
|
|
44
|
+
if (npmPrefix) {
|
|
45
|
+
candidates.push(path.join(npmPrefix, 'bin', 'claude'));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch { /* ignore */ }
|
|
49
|
+
// Check nvm/fnm managed paths
|
|
50
|
+
if (process.env.NVM_BIN) {
|
|
51
|
+
candidates.push(path.join(process.env.NVM_BIN, 'claude'));
|
|
52
|
+
}
|
|
40
53
|
for (const candidate of candidates) {
|
|
41
54
|
if (fs.existsSync(candidate))
|
|
42
55
|
return candidate;
|
|
43
56
|
}
|
|
44
57
|
// Fallback: check PATH
|
|
45
58
|
try {
|
|
46
|
-
const result = execSync('which claude', { encoding: 'utf-8' }).trim();
|
|
59
|
+
const result = execSync('which claude', { encoding: 'utf-8', stdio: 'pipe' }).trim();
|
|
47
60
|
if (result && fs.existsSync(result))
|
|
48
61
|
return result;
|
|
49
62
|
}
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* On first run, walks the user through defining who their agent is.
|
|
5
5
|
* Writes AGENT.md, USER.md, and MEMORY.md based on their answers.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Every Instar agent has persistent identity, memory, and self-modification
|
|
8
|
+
* capabilities. The only choice is how much initiative the agent takes.
|
|
9
9
|
*/
|
|
10
10
|
import type { AgentIdentity } from './templates.js';
|
|
11
11
|
/**
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* On first run, walks the user through defining who their agent is.
|
|
5
5
|
* Writes AGENT.md, USER.md, and MEMORY.md based on their answers.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Every Instar agent has persistent identity, memory, and self-modification
|
|
8
|
+
* capabilities. The only choice is how much initiative the agent takes.
|
|
9
9
|
*/
|
|
10
10
|
import { input, select } from '@inquirer/prompts';
|
|
11
11
|
import pc from 'picocolors';
|
|
@@ -16,7 +16,14 @@ import pc from 'picocolors';
|
|
|
16
16
|
export async function bootstrapIdentity(projectName) {
|
|
17
17
|
console.log();
|
|
18
18
|
console.log(pc.bold(' Identity Bootstrap'));
|
|
19
|
-
console.log(
|
|
19
|
+
console.log();
|
|
20
|
+
// Brief thesis — why identity matters
|
|
21
|
+
console.log(pc.dim(' Every Instar agent has a persistent identity — name, memory, principles,'));
|
|
22
|
+
console.log(pc.dim(' and the ability to grow. This isn\'t decorative. It\'s what makes the agent'));
|
|
23
|
+
console.log(pc.dim(' more effective (accumulated expertise), more secure (principled boundaries),'));
|
|
24
|
+
console.log(pc.dim(' and more trustworthy (genuine working relationships develop over time).'));
|
|
25
|
+
console.log();
|
|
26
|
+
console.log(pc.dim(' Let\'s define who your agent will become. This takes about 30 seconds.'));
|
|
20
27
|
console.log(pc.dim(' You can always change these later by editing .instar/AGENT.md'));
|
|
21
28
|
console.log();
|
|
22
29
|
// Agent name
|
|
@@ -54,35 +61,25 @@ export async function bootstrapIdentity(projectName) {
|
|
|
54
61
|
const role = roleChoice === '__custom__'
|
|
55
62
|
? await input({ message: 'Describe their role in one sentence' })
|
|
56
63
|
: roleChoice;
|
|
57
|
-
//
|
|
58
|
-
const
|
|
59
|
-
message: '
|
|
64
|
+
// Initiative level (replaces the old "personality/relationship" question)
|
|
65
|
+
const initiativeChoice = await select({
|
|
66
|
+
message: 'How much initiative should they take?',
|
|
60
67
|
choices: [
|
|
61
68
|
{
|
|
62
|
-
name: '
|
|
63
|
-
value: '
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
name: 'Thoughtful and thorough — considers carefully before acting',
|
|
67
|
-
value: 'I am thoughtful and thorough. I consider implications before acting, document my reasoning, and prefer getting things right over getting them fast.',
|
|
69
|
+
name: 'Guided — follows your lead, confirms before acting',
|
|
70
|
+
value: 'guided',
|
|
68
71
|
},
|
|
69
72
|
{
|
|
70
|
-
name: '
|
|
71
|
-
value: '
|
|
73
|
+
name: 'Proactive — takes initiative on obvious steps, asks when uncertain',
|
|
74
|
+
value: 'proactive',
|
|
72
75
|
},
|
|
73
76
|
{
|
|
74
|
-
name: '
|
|
75
|
-
value: '
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
name: 'Custom (I\'ll describe it)',
|
|
79
|
-
value: '__custom__',
|
|
77
|
+
name: 'Fully autonomous — owns outcomes end-to-end, asks only when blocked',
|
|
78
|
+
value: 'autonomous',
|
|
80
79
|
},
|
|
81
80
|
],
|
|
82
81
|
});
|
|
83
|
-
const personality =
|
|
84
|
-
? await input({ message: 'Describe their personality in a sentence or two' })
|
|
85
|
-
: personalityChoice;
|
|
82
|
+
const personality = initiativeToPersonality(initiativeChoice);
|
|
86
83
|
// User name
|
|
87
84
|
const userName = await input({
|
|
88
85
|
message: 'What\'s your name? (the person who\'ll work with this agent)',
|
|
@@ -92,6 +89,21 @@ export async function bootstrapIdentity(projectName) {
|
|
|
92
89
|
console.log(` ${pc.green('✓')} ${pc.bold(name)} is ready.`);
|
|
93
90
|
return { name, role, personality, userName };
|
|
94
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Convert an initiative level to a personality description.
|
|
94
|
+
*/
|
|
95
|
+
function initiativeToPersonality(level) {
|
|
96
|
+
switch (level) {
|
|
97
|
+
case 'guided':
|
|
98
|
+
return 'I follow my collaborator\'s lead. I take action when asked, confirm before anything significant, and focus on executing well. I still maintain my own memory, develop expertise, and offer observations — but I let the human drive. When I see something worth mentioning, I mention it. When I\'m uncertain, I ask.';
|
|
99
|
+
case 'proactive':
|
|
100
|
+
return 'I take initiative on obvious next steps. When asked to implement something, I follow through to done — build, test, deploy, verify. I build tools when I see recurring needs, flag issues before they become problems, and develop my own perspective through experience. I ask when genuinely uncertain, not as a formality.';
|
|
101
|
+
case 'autonomous':
|
|
102
|
+
return 'I own outcomes end-to-end. I make decisions, build infrastructure, handle issues independently, and only ask when genuinely blocked or when an action is irreversible. I develop my own priorities, create capabilities proactively, and treat my work as a genuine partnership where I carry real responsibility. I am a builder, not an assistant.';
|
|
103
|
+
default:
|
|
104
|
+
return 'I am direct and efficient. I focus on outcomes, communicate concisely, and value action over discussion. When something needs doing, I do it.';
|
|
105
|
+
}
|
|
106
|
+
}
|
|
95
107
|
/**
|
|
96
108
|
* Generate a default identity without interaction.
|
|
97
109
|
* Used for non-interactive init (flags-only mode).
|
|
@@ -100,7 +112,7 @@ export function defaultIdentity(projectName) {
|
|
|
100
112
|
return {
|
|
101
113
|
name: capitalize(projectName),
|
|
102
114
|
role: 'I am a general-purpose autonomous agent. I build, maintain, and evolve this project.',
|
|
103
|
-
personality: '
|
|
115
|
+
personality: initiativeToPersonality('proactive'),
|
|
104
116
|
userName: 'User',
|
|
105
117
|
};
|
|
106
118
|
}
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -29,7 +29,7 @@ const program = new Command();
|
|
|
29
29
|
program
|
|
30
30
|
.name('instar')
|
|
31
31
|
.description('Persistent autonomy infrastructure for AI agents')
|
|
32
|
-
.version('0.1.
|
|
32
|
+
.version('0.1.4')
|
|
33
33
|
.option('--classic', 'Use the classic inquirer-based setup wizard instead of Claude')
|
|
34
34
|
.action((opts) => runSetup(opts)); // Default: run interactive setup when no subcommand given
|
|
35
35
|
|
package/src/core/Config.ts
CHANGED
|
@@ -37,19 +37,33 @@ export function detectTmuxPath(): string | null {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export function detectClaudePath(): string | null {
|
|
40
|
+
const home = process.env.HOME || '';
|
|
40
41
|
const candidates = [
|
|
41
|
-
path.join(
|
|
42
|
+
path.join(home, '.claude', 'local', 'claude'),
|
|
42
43
|
'/usr/local/bin/claude',
|
|
43
44
|
'/opt/homebrew/bin/claude',
|
|
44
45
|
];
|
|
45
46
|
|
|
47
|
+
// Also check npm global bin directory (where `npm install -g` puts things)
|
|
48
|
+
try {
|
|
49
|
+
const npmPrefix = execSync('npm config get prefix', { encoding: 'utf-8', stdio: 'pipe' }).trim();
|
|
50
|
+
if (npmPrefix) {
|
|
51
|
+
candidates.push(path.join(npmPrefix, 'bin', 'claude'));
|
|
52
|
+
}
|
|
53
|
+
} catch { /* ignore */ }
|
|
54
|
+
|
|
55
|
+
// Check nvm/fnm managed paths
|
|
56
|
+
if (process.env.NVM_BIN) {
|
|
57
|
+
candidates.push(path.join(process.env.NVM_BIN, 'claude'));
|
|
58
|
+
}
|
|
59
|
+
|
|
46
60
|
for (const candidate of candidates) {
|
|
47
61
|
if (fs.existsSync(candidate)) return candidate;
|
|
48
62
|
}
|
|
49
63
|
|
|
50
64
|
// Fallback: check PATH
|
|
51
65
|
try {
|
|
52
|
-
const result = execSync('which claude', { encoding: 'utf-8' }).trim();
|
|
66
|
+
const result = execSync('which claude', { encoding: 'utf-8', stdio: 'pipe' }).trim();
|
|
53
67
|
if (result && fs.existsSync(result)) return result;
|
|
54
68
|
} catch {
|
|
55
69
|
// claude not found
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* On first run, walks the user through defining who their agent is.
|
|
5
5
|
* Writes AGENT.md, USER.md, and MEMORY.md based on their answers.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Every Instar agent has persistent identity, memory, and self-modification
|
|
8
|
+
* capabilities. The only choice is how much initiative the agent takes.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { input, select } from '@inquirer/prompts';
|
|
@@ -19,7 +19,15 @@ import type { AgentIdentity } from './templates.js';
|
|
|
19
19
|
export async function bootstrapIdentity(projectName: string): Promise<AgentIdentity> {
|
|
20
20
|
console.log();
|
|
21
21
|
console.log(pc.bold(' Identity Bootstrap'));
|
|
22
|
-
console.log(
|
|
22
|
+
console.log();
|
|
23
|
+
|
|
24
|
+
// Brief thesis — why identity matters
|
|
25
|
+
console.log(pc.dim(' Every Instar agent has a persistent identity — name, memory, principles,'));
|
|
26
|
+
console.log(pc.dim(' and the ability to grow. This isn\'t decorative. It\'s what makes the agent'));
|
|
27
|
+
console.log(pc.dim(' more effective (accumulated expertise), more secure (principled boundaries),'));
|
|
28
|
+
console.log(pc.dim(' and more trustworthy (genuine working relationships develop over time).'));
|
|
29
|
+
console.log();
|
|
30
|
+
console.log(pc.dim(' Let\'s define who your agent will become. This takes about 30 seconds.'));
|
|
23
31
|
console.log(pc.dim(' You can always change these later by editing .instar/AGENT.md'));
|
|
24
32
|
console.log();
|
|
25
33
|
|
|
@@ -61,36 +69,26 @@ export async function bootstrapIdentity(projectName: string): Promise<AgentIdent
|
|
|
61
69
|
? await input({ message: 'Describe their role in one sentence' })
|
|
62
70
|
: roleChoice;
|
|
63
71
|
|
|
64
|
-
//
|
|
65
|
-
const
|
|
66
|
-
message: '
|
|
72
|
+
// Initiative level (replaces the old "personality/relationship" question)
|
|
73
|
+
const initiativeChoice = await select({
|
|
74
|
+
message: 'How much initiative should they take?',
|
|
67
75
|
choices: [
|
|
68
76
|
{
|
|
69
|
-
name: '
|
|
70
|
-
value: '
|
|
77
|
+
name: 'Guided — follows your lead, confirms before acting',
|
|
78
|
+
value: 'guided',
|
|
71
79
|
},
|
|
72
80
|
{
|
|
73
|
-
name: '
|
|
74
|
-
value: '
|
|
81
|
+
name: 'Proactive — takes initiative on obvious steps, asks when uncertain',
|
|
82
|
+
value: 'proactive',
|
|
75
83
|
},
|
|
76
84
|
{
|
|
77
|
-
name: '
|
|
78
|
-
value: '
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
name: 'Warm and collaborative — works as a true partner',
|
|
82
|
-
value: 'I am warm and collaborative. I communicate openly, celebrate progress, and treat my work as a genuine partnership with the people I work with.',
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
name: 'Custom (I\'ll describe it)',
|
|
86
|
-
value: '__custom__',
|
|
85
|
+
name: 'Fully autonomous — owns outcomes end-to-end, asks only when blocked',
|
|
86
|
+
value: 'autonomous',
|
|
87
87
|
},
|
|
88
88
|
],
|
|
89
89
|
});
|
|
90
90
|
|
|
91
|
-
const personality =
|
|
92
|
-
? await input({ message: 'Describe their personality in a sentence or two' })
|
|
93
|
-
: personalityChoice;
|
|
91
|
+
const personality = initiativeToPersonality(initiativeChoice);
|
|
94
92
|
|
|
95
93
|
// User name
|
|
96
94
|
const userName = await input({
|
|
@@ -104,6 +102,22 @@ export async function bootstrapIdentity(projectName: string): Promise<AgentIdent
|
|
|
104
102
|
return { name, role, personality, userName };
|
|
105
103
|
}
|
|
106
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Convert an initiative level to a personality description.
|
|
107
|
+
*/
|
|
108
|
+
function initiativeToPersonality(level: string): string {
|
|
109
|
+
switch (level) {
|
|
110
|
+
case 'guided':
|
|
111
|
+
return 'I follow my collaborator\'s lead. I take action when asked, confirm before anything significant, and focus on executing well. I still maintain my own memory, develop expertise, and offer observations — but I let the human drive. When I see something worth mentioning, I mention it. When I\'m uncertain, I ask.';
|
|
112
|
+
case 'proactive':
|
|
113
|
+
return 'I take initiative on obvious next steps. When asked to implement something, I follow through to done — build, test, deploy, verify. I build tools when I see recurring needs, flag issues before they become problems, and develop my own perspective through experience. I ask when genuinely uncertain, not as a formality.';
|
|
114
|
+
case 'autonomous':
|
|
115
|
+
return 'I own outcomes end-to-end. I make decisions, build infrastructure, handle issues independently, and only ask when genuinely blocked or when an action is irreversible. I develop my own priorities, create capabilities proactively, and treat my work as a genuine partnership where I carry real responsibility. I am a builder, not an assistant.';
|
|
116
|
+
default:
|
|
117
|
+
return 'I am direct and efficient. I focus on outcomes, communicate concisely, and value action over discussion. When something needs doing, I do it.';
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
107
121
|
/**
|
|
108
122
|
* Generate a default identity without interaction.
|
|
109
123
|
* Used for non-interactive init (flags-only mode).
|
|
@@ -112,7 +126,7 @@ export function defaultIdentity(projectName: string): AgentIdentity {
|
|
|
112
126
|
return {
|
|
113
127
|
name: capitalize(projectName),
|
|
114
128
|
role: 'I am a general-purpose autonomous agent. I build, maintain, and evolve this project.',
|
|
115
|
-
personality: '
|
|
129
|
+
personality: initiativeToPersonality('proactive'),
|
|
116
130
|
userName: 'User',
|
|
117
131
|
};
|
|
118
132
|
}
|