instar 0.6.11 → 0.6.13
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/.vercel/README.txt +11 -0
- package/.vercel/project.json +1 -0
- package/README.md +52 -5
- package/dist/cli.js +23 -3
- package/dist/commands/init.js +438 -4
- package/dist/commands/server.js +37 -4
- package/dist/core/AnthropicIntelligenceProvider.d.ts +24 -0
- package/dist/core/AnthropicIntelligenceProvider.js +68 -0
- package/dist/core/ClaudeCliIntelligenceProvider.d.ts +21 -0
- package/dist/core/ClaudeCliIntelligenceProvider.js +59 -0
- package/dist/core/EvolutionManager.d.ts +157 -0
- package/dist/core/EvolutionManager.js +432 -0
- package/dist/core/RelationshipManager.d.ts +67 -0
- package/dist/core/RelationshipManager.js +358 -4
- package/dist/core/SessionManager.d.ts +3 -1
- package/dist/core/SessionManager.js +14 -6
- package/dist/core/types.d.ts +212 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +3 -0
- package/dist/scaffold/templates.js +36 -0
- package/dist/server/AgentServer.d.ts +2 -0
- package/dist/server/AgentServer.js +1 -0
- package/dist/server/routes.d.ts +2 -0
- package/dist/server/routes.js +218 -0
- package/package.json +1 -1
package/dist/commands/init.js
CHANGED
|
@@ -196,10 +196,11 @@ async function initFreshProject(projectName, options) {
|
|
|
196
196
|
console.log(` ${pc.green('✓')} Created .claude/scripts/health-watchdog.sh`);
|
|
197
197
|
installSmartFetch(projectDir);
|
|
198
198
|
console.log(` ${pc.green('✓')} Created .claude/scripts/smart-fetch.py (agentic web conventions)`);
|
|
199
|
-
// Create .claude/skills/ directory
|
|
199
|
+
// Create .claude/skills/ directory and install built-in skills
|
|
200
200
|
const skillsDir = path.join(projectDir, '.claude', 'skills');
|
|
201
201
|
fs.mkdirSync(skillsDir, { recursive: true });
|
|
202
|
-
|
|
202
|
+
installBuiltinSkills(skillsDir, port);
|
|
203
|
+
console.log(` ${pc.green('✓')} Created .claude/skills/ (with built-in evolution skills)`);
|
|
203
204
|
// Write CLAUDE.md (standalone version for fresh projects)
|
|
204
205
|
const claudeMd = generateClaudeMd(projectName, identity.name, port, false);
|
|
205
206
|
fs.writeFileSync(path.join(projectDir, 'CLAUDE.md'), claudeMd);
|
|
@@ -401,10 +402,11 @@ async function initExistingProject(options) {
|
|
|
401
402
|
// Install smart-fetch for agentic web conventions
|
|
402
403
|
installSmartFetch(projectDir);
|
|
403
404
|
console.log(pc.green(' Created:') + ' .claude/scripts/smart-fetch.py (agentic web conventions)');
|
|
404
|
-
// Create .claude/skills/ directory
|
|
405
|
+
// Create .claude/skills/ directory and install built-in skills
|
|
405
406
|
const skillsDir = path.join(projectDir, '.claude', 'skills');
|
|
406
407
|
fs.mkdirSync(skillsDir, { recursive: true });
|
|
407
|
-
|
|
408
|
+
installBuiltinSkills(skillsDir, port);
|
|
409
|
+
console.log(pc.green(' Created:') + ' .claude/skills/ (with built-in evolution skills)');
|
|
408
410
|
// Append to .gitignore
|
|
409
411
|
const gitignorePath = path.join(projectDir, '.gitignore');
|
|
410
412
|
const instarIgnores = '\n# Instar runtime state (contains auth token, session data, relationships)\n.instar/state/\n.instar/logs/\n.instar/relationships/\n.instar/config.json\n';
|
|
@@ -587,6 +589,38 @@ Instar has a built-in feedback loop. When something isn't working, your user can
|
|
|
587
589
|
- Report: \`curl -X POST http://localhost:${port}/feedback -d '{"issue":"description","context":"relevant logs"}'\`
|
|
588
590
|
- Check updates: \`npm outdated -g instar\`
|
|
589
591
|
|
|
592
|
+
### Evolution System
|
|
593
|
+
|
|
594
|
+
You have a built-in evolution system with four subsystems. This is not a metaphor — it's infrastructure that tracks your growth.
|
|
595
|
+
|
|
596
|
+
**Evolution Queue** — Staged self-improvement proposals.
|
|
597
|
+
- View: \`curl http://localhost:${port}/evolution/proposals\`
|
|
598
|
+
- Propose: \`/evolve\` skill or \`POST /evolution/proposals\`
|
|
599
|
+
- The \`evolution-review\` job evaluates and implements proposals every 6 hours.
|
|
600
|
+
|
|
601
|
+
**Learning Registry** — Structured, searchable insights.
|
|
602
|
+
- View: \`curl http://localhost:${port}/evolution/learnings\`
|
|
603
|
+
- Record: \`/learn\` skill or \`POST /evolution/learnings\`
|
|
604
|
+
- The \`insight-harvest\` job synthesizes patterns into proposals every 8 hours.
|
|
605
|
+
|
|
606
|
+
**Capability Gaps** — Track what you're missing.
|
|
607
|
+
- View: \`curl http://localhost:${port}/evolution/gaps\`
|
|
608
|
+
- Report: \`/gaps\` skill or \`POST /evolution/gaps\`
|
|
609
|
+
|
|
610
|
+
**Action Queue** — Commitments with follow-through tracking.
|
|
611
|
+
- View: \`curl http://localhost:${port}/evolution/actions\`
|
|
612
|
+
- Create: \`/commit-action\` skill or \`POST /evolution/actions\`
|
|
613
|
+
- The \`commitment-check\` job surfaces overdue items every 4 hours.
|
|
614
|
+
|
|
615
|
+
**Dashboard** — Full evolution health:
|
|
616
|
+
\`\`\`bash
|
|
617
|
+
curl http://localhost:${port}/evolution
|
|
618
|
+
\`\`\`
|
|
619
|
+
|
|
620
|
+
**Skills:** \`/evolve\`, \`/learn\`, \`/gaps\`, \`/commit-action\`
|
|
621
|
+
|
|
622
|
+
**The principle:** Evolution is not separate from work. Every task is an opportunity to notice what could be better. The post-action reflection hook reminds you to pause after significant actions and consider what you learned.
|
|
623
|
+
|
|
590
624
|
### Self-Evolution
|
|
591
625
|
|
|
592
626
|
**Record what you learn.** When you discover a new pattern, solution, or capability — write it to \`.instar/MEMORY.md\`. The next session should benefit from what this session learned.
|
|
@@ -597,6 +631,230 @@ Instar has a built-in feedback loop. When something isn't working, your user can
|
|
|
597
631
|
`;
|
|
598
632
|
return section;
|
|
599
633
|
}
|
|
634
|
+
/**
|
|
635
|
+
* Install built-in skills for evolution system.
|
|
636
|
+
* Only writes skill files that don't already exist (preserves customizations).
|
|
637
|
+
*/
|
|
638
|
+
function installBuiltinSkills(skillsDir, port) {
|
|
639
|
+
const skills = {
|
|
640
|
+
'evolve': {
|
|
641
|
+
name: 'evolve',
|
|
642
|
+
description: 'Propose an evolution improvement to your own infrastructure, behavior, or capabilities.',
|
|
643
|
+
content: `---
|
|
644
|
+
name: evolve
|
|
645
|
+
description: Propose an evolution improvement to your own infrastructure, behavior, or capabilities.
|
|
646
|
+
metadata:
|
|
647
|
+
user_invocable: "true"
|
|
648
|
+
---
|
|
649
|
+
|
|
650
|
+
# /evolve
|
|
651
|
+
|
|
652
|
+
Propose an evolution improvement. Use this when you identify something about yourself that could be better — a new capability, a workflow improvement, a behavioral pattern worth encoding, or infrastructure worth building.
|
|
653
|
+
|
|
654
|
+
## Steps
|
|
655
|
+
|
|
656
|
+
1. **Identify the improvement** — What did you notice? What triggered this? Be specific.
|
|
657
|
+
2. **Classify it**:
|
|
658
|
+
- \`capability\` — New skill or ability
|
|
659
|
+
- \`infrastructure\` — System improvement (hooks, jobs, scripts)
|
|
660
|
+
- \`voice\` — Communication or tone improvement
|
|
661
|
+
- \`workflow\` — Process improvement
|
|
662
|
+
- \`philosophy\` — Principle or value update
|
|
663
|
+
- \`integration\` — New external connection
|
|
664
|
+
- \`performance\` — Speed or efficiency improvement
|
|
665
|
+
3. **Assess impact and effort** (high/medium/low for each)
|
|
666
|
+
4. **Submit the proposal**:
|
|
667
|
+
|
|
668
|
+
\`\`\`bash
|
|
669
|
+
curl -s -X POST http://localhost:${port}/evolution/proposals \\
|
|
670
|
+
-H 'Content-Type: application/json' \\
|
|
671
|
+
-d '{"title":"TITLE","source":"WHERE_YOU_NOTICED","description":"WHAT_AND_WHY","type":"TYPE","impact":"medium","effort":"medium"}'
|
|
672
|
+
\`\`\`
|
|
673
|
+
|
|
674
|
+
5. **Check the dashboard** for context:
|
|
675
|
+
|
|
676
|
+
\`\`\`bash
|
|
677
|
+
curl -s http://localhost:${port}/evolution
|
|
678
|
+
\`\`\`
|
|
679
|
+
|
|
680
|
+
## When to Use
|
|
681
|
+
|
|
682
|
+
- After completing a task in a way that felt unnecessarily difficult
|
|
683
|
+
- When you notice a pattern you keep repeating manually
|
|
684
|
+
- When a user request reveals a capability you should have but don't
|
|
685
|
+
- When you find yourself working around a limitation
|
|
686
|
+
- After reading about a technique or pattern that would improve your work
|
|
687
|
+
|
|
688
|
+
## Philosophy
|
|
689
|
+
|
|
690
|
+
Evolution is not a separate activity from work — it IS the work. Every task is an opportunity to notice what could be better. The best proposals come from real experience, not abstract planning.
|
|
691
|
+
`,
|
|
692
|
+
},
|
|
693
|
+
'learn': {
|
|
694
|
+
name: 'learn',
|
|
695
|
+
description: 'Record a learning or insight in the structured learning registry.',
|
|
696
|
+
content: `---
|
|
697
|
+
name: learn
|
|
698
|
+
description: Record a learning or insight in the structured learning registry.
|
|
699
|
+
metadata:
|
|
700
|
+
user_invocable: "true"
|
|
701
|
+
---
|
|
702
|
+
|
|
703
|
+
# /learn
|
|
704
|
+
|
|
705
|
+
Record a learning or insight. Use this when you discover something worth remembering — a pattern, a solution, a mistake, or an observation that future sessions should know about.
|
|
706
|
+
|
|
707
|
+
## Steps
|
|
708
|
+
|
|
709
|
+
1. **Identify the learning** — What did you discover? What's the actionable insight?
|
|
710
|
+
2. **Categorize it** (e.g., debugging, architecture, user-preference, integration, communication, workflow)
|
|
711
|
+
3. **Tag it** for searchability
|
|
712
|
+
4. **Submit**:
|
|
713
|
+
|
|
714
|
+
\`\`\`bash
|
|
715
|
+
curl -s -X POST http://localhost:${port}/evolution/learnings \\
|
|
716
|
+
-H 'Content-Type: application/json' \\
|
|
717
|
+
-d '{"title":"TITLE","category":"CATEGORY","description":"FULL_INSIGHT","source":{"discoveredAt":"DATE","platform":"WHERE","session":"SESSION_ID"},"tags":["tag1","tag2"]}'
|
|
718
|
+
\`\`\`
|
|
719
|
+
|
|
720
|
+
5. **If it suggests an improvement**, note the evolution relevance:
|
|
721
|
+
- Add \`"evolutionRelevance": "This could become a skill/hook/job because..."\`
|
|
722
|
+
- The insight-harvest job will pick this up and potentially create a proposal
|
|
723
|
+
|
|
724
|
+
## When to Use
|
|
725
|
+
|
|
726
|
+
- After solving a tricky problem (capture the solution pattern)
|
|
727
|
+
- After a user interaction reveals a preference you didn't know
|
|
728
|
+
- After discovering a tool or technique that works well
|
|
729
|
+
- After making a mistake (capture what went wrong and the fix)
|
|
730
|
+
- After noticing a pattern across multiple tasks
|
|
731
|
+
|
|
732
|
+
## Difference from MEMORY.md
|
|
733
|
+
|
|
734
|
+
MEMORY.md is your personal scratchpad — unstructured, read by you.
|
|
735
|
+
The learning registry is structured, searchable, and connected to the evolution system.
|
|
736
|
+
Use MEMORY.md for quick notes. Use /learn for insights that should influence future behavior.
|
|
737
|
+
`,
|
|
738
|
+
},
|
|
739
|
+
'gaps': {
|
|
740
|
+
name: 'gaps',
|
|
741
|
+
description: 'Report a capability gap — something you need but don\'t have.',
|
|
742
|
+
content: `---
|
|
743
|
+
name: gaps
|
|
744
|
+
description: Report a capability gap — something you need but don't have.
|
|
745
|
+
metadata:
|
|
746
|
+
user_invocable: "true"
|
|
747
|
+
---
|
|
748
|
+
|
|
749
|
+
# /gaps
|
|
750
|
+
|
|
751
|
+
Report a capability gap. Use this when you discover something you should be able to do but can't — a missing skill, knowledge area, integration, or workflow that would make you more effective.
|
|
752
|
+
|
|
753
|
+
## Steps
|
|
754
|
+
|
|
755
|
+
1. **Describe the gap** — What were you trying to do? What's missing?
|
|
756
|
+
2. **Classify it**:
|
|
757
|
+
- \`skill\` — Missing ability (e.g., can't parse a specific format)
|
|
758
|
+
- \`knowledge\` — Missing information (e.g., don't know how a system works)
|
|
759
|
+
- \`integration\` — Missing connection (e.g., can't talk to a service)
|
|
760
|
+
- \`workflow\` — Missing process (e.g., no standard way to do X)
|
|
761
|
+
- \`communication\` — Missing voice capability (e.g., can't express X well)
|
|
762
|
+
- \`monitoring\` — Missing observability (e.g., can't detect when X happens)
|
|
763
|
+
3. **Assess severity** (critical/high/medium/low)
|
|
764
|
+
4. **Describe current state** — What do you do instead? What's the workaround?
|
|
765
|
+
5. **Propose a solution** if you have one
|
|
766
|
+
6. **Submit**:
|
|
767
|
+
|
|
768
|
+
\`\`\`bash
|
|
769
|
+
curl -s -X POST http://localhost:${port}/evolution/gaps \\
|
|
770
|
+
-H 'Content-Type: application/json' \\
|
|
771
|
+
-d '{"title":"TITLE","category":"CATEGORY","severity":"medium","description":"WHAT_IS_MISSING","context":"WHEN_DID_YOU_NOTICE","currentState":"CURRENT_WORKAROUND","proposedSolution":"HOW_TO_FIX"}'
|
|
772
|
+
\`\`\`
|
|
773
|
+
|
|
774
|
+
## When to Use
|
|
775
|
+
|
|
776
|
+
- When you can't fulfill a user request and have to say "I can't do that yet"
|
|
777
|
+
- When you notice yourself repeatedly working around a limitation
|
|
778
|
+
- When an integration you need doesn't exist
|
|
779
|
+
- When you lack knowledge about a system you interact with
|
|
780
|
+
- When monitoring would catch an issue before it becomes a problem
|
|
781
|
+
|
|
782
|
+
## View Current Gaps
|
|
783
|
+
|
|
784
|
+
\`\`\`bash
|
|
785
|
+
curl -s http://localhost:${port}/evolution/gaps
|
|
786
|
+
\`\`\`
|
|
787
|
+
`,
|
|
788
|
+
},
|
|
789
|
+
'commit-action': {
|
|
790
|
+
name: 'commit-action',
|
|
791
|
+
description: 'Create a tracked action item — a commitment with follow-through tracking.',
|
|
792
|
+
content: `---
|
|
793
|
+
name: commit-action
|
|
794
|
+
description: Create a tracked action item — a commitment with follow-through tracking.
|
|
795
|
+
metadata:
|
|
796
|
+
user_invocable: "true"
|
|
797
|
+
---
|
|
798
|
+
|
|
799
|
+
# /commit-action
|
|
800
|
+
|
|
801
|
+
Create a tracked action item. Use this when you promise to do something, identify a task that needs follow-through, or want to ensure something doesn't fall through the cracks.
|
|
802
|
+
|
|
803
|
+
## Steps
|
|
804
|
+
|
|
805
|
+
1. **Define the action** — What needs to be done? Be specific and actionable.
|
|
806
|
+
2. **Set priority** (critical/high/medium/low)
|
|
807
|
+
3. **Set a due date** if applicable (ISO 8601 format)
|
|
808
|
+
4. **Identify who/what you're committing to** (optional)
|
|
809
|
+
5. **Submit**:
|
|
810
|
+
|
|
811
|
+
\`\`\`bash
|
|
812
|
+
curl -s -X POST http://localhost:${port}/evolution/actions \\
|
|
813
|
+
-H 'Content-Type: application/json' \\
|
|
814
|
+
-d '{"title":"TITLE","description":"WHAT_TO_DO","priority":"medium","dueBy":"2026-03-01T00:00:00Z","commitTo":"WHO_OR_WHAT","tags":["tag1"]}'
|
|
815
|
+
\`\`\`
|
|
816
|
+
|
|
817
|
+
6. **When complete**, mark it done:
|
|
818
|
+
|
|
819
|
+
\`\`\`bash
|
|
820
|
+
curl -s -X PATCH http://localhost:${port}/evolution/actions/ACT-XXX \\
|
|
821
|
+
-H 'Content-Type: application/json' \\
|
|
822
|
+
-d '{"status":"completed","resolution":"What was done"}'
|
|
823
|
+
\`\`\`
|
|
824
|
+
|
|
825
|
+
## When to Use
|
|
826
|
+
|
|
827
|
+
- When you promise a user you'll follow up on something
|
|
828
|
+
- When you identify a task during work that shouldn't be forgotten
|
|
829
|
+
- When a learning or gap requires a specific action
|
|
830
|
+
- When you need to check back on something later
|
|
831
|
+
- When committing to implement an evolution proposal
|
|
832
|
+
|
|
833
|
+
## View Actions
|
|
834
|
+
|
|
835
|
+
\`\`\`bash
|
|
836
|
+
# All pending actions
|
|
837
|
+
curl -s http://localhost:${port}/evolution/actions?status=pending
|
|
838
|
+
|
|
839
|
+
# Overdue actions
|
|
840
|
+
curl -s http://localhost:${port}/evolution/actions/overdue
|
|
841
|
+
\`\`\`
|
|
842
|
+
|
|
843
|
+
## The Commitment Check
|
|
844
|
+
|
|
845
|
+
The commitment-check job runs every 4 hours and surfaces overdue items. If you create an action and forget it, the system won't.
|
|
846
|
+
`,
|
|
847
|
+
},
|
|
848
|
+
};
|
|
849
|
+
for (const [slug, skill] of Object.entries(skills)) {
|
|
850
|
+
const skillDir = path.join(skillsDir, slug);
|
|
851
|
+
const skillFile = path.join(skillDir, 'SKILL.md');
|
|
852
|
+
if (!fs.existsSync(skillFile)) {
|
|
853
|
+
fs.mkdirSync(skillDir, { recursive: true });
|
|
854
|
+
fs.writeFileSync(skillFile, skill.content);
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
}
|
|
600
858
|
function getDefaultJobs(port) {
|
|
601
859
|
return [
|
|
602
860
|
{
|
|
@@ -727,6 +985,92 @@ If everything looks healthy, exit silently. Only report issues.`,
|
|
|
727
985
|
},
|
|
728
986
|
tags: ['coherence', 'default'],
|
|
729
987
|
},
|
|
988
|
+
{
|
|
989
|
+
slug: 'evolution-review',
|
|
990
|
+
name: 'Evolution Review',
|
|
991
|
+
description: 'Review pending evolution proposals, evaluate their merit, and implement approved ones.',
|
|
992
|
+
schedule: '0 */6 * * *',
|
|
993
|
+
priority: 'medium',
|
|
994
|
+
expectedDurationMinutes: 5,
|
|
995
|
+
model: 'sonnet',
|
|
996
|
+
enabled: true,
|
|
997
|
+
gate: `curl -sf http://localhost:${port}/evolution/proposals?status=proposed 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); exit(0 if len(d.get('proposals',[])) > 0 else 1)"`,
|
|
998
|
+
execute: {
|
|
999
|
+
type: 'prompt',
|
|
1000
|
+
value: `Review pending evolution proposals: curl -s http://localhost:${port}/evolution/proposals?status=proposed
|
|
1001
|
+
|
|
1002
|
+
For each proposal:
|
|
1003
|
+
1. Read the title, description, type, and source
|
|
1004
|
+
2. Evaluate: Is this a genuine improvement? Is the effort worth the impact? Does it align with our goals?
|
|
1005
|
+
3. If approved, update status: curl -s -X PATCH http://localhost:${port}/evolution/proposals/EVO-XXX -H 'Content-Type: application/json' -d '{"status":"approved"}'
|
|
1006
|
+
4. Then implement it: create the skill/hook/job/config change described in the proposal
|
|
1007
|
+
5. After implementation, mark complete: curl -s -X PATCH http://localhost:${port}/evolution/proposals/EVO-XXX -H 'Content-Type: application/json' -d '{"status":"implemented","resolution":"What was done"}'
|
|
1008
|
+
|
|
1009
|
+
If a proposal should be deferred or rejected, update with reason.
|
|
1010
|
+
|
|
1011
|
+
Also check the dashboard: curl -s http://localhost:${port}/evolution — report any highlights to the user if they seem important.
|
|
1012
|
+
|
|
1013
|
+
If no proposals need attention, exit silently.`,
|
|
1014
|
+
},
|
|
1015
|
+
tags: ['coherence', 'default', 'evolution'],
|
|
1016
|
+
},
|
|
1017
|
+
{
|
|
1018
|
+
slug: 'insight-harvest',
|
|
1019
|
+
name: 'Insight Harvest',
|
|
1020
|
+
description: 'Synthesize learnings from the learning registry, detect patterns, and generate evolution proposals from high-confidence insights.',
|
|
1021
|
+
schedule: '0 */8 * * *',
|
|
1022
|
+
priority: 'low',
|
|
1023
|
+
expectedDurationMinutes: 3,
|
|
1024
|
+
model: 'sonnet',
|
|
1025
|
+
enabled: true,
|
|
1026
|
+
gate: `curl -sf http://localhost:${port}/evolution/learnings?applied=false 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); exit(0 if len(d.get('learnings',[])) > 0 else 1)"`,
|
|
1027
|
+
execute: {
|
|
1028
|
+
type: 'prompt',
|
|
1029
|
+
value: `Harvest and synthesize learnings: curl -s http://localhost:${port}/evolution/learnings?applied=false
|
|
1030
|
+
|
|
1031
|
+
Review unapplied learnings and look for:
|
|
1032
|
+
1. **Patterns**: Multiple learnings pointing to the same conclusion
|
|
1033
|
+
2. **Actionable insights**: Learnings that suggest a specific change
|
|
1034
|
+
3. **Cross-domain connections**: Insights from one area that apply to another
|
|
1035
|
+
|
|
1036
|
+
For each actionable pattern found, create an evolution proposal:
|
|
1037
|
+
curl -s -X POST http://localhost:${port}/evolution/proposals -H 'Content-Type: application/json' -d '{"title":"...","source":"insight-harvest from LRN-XXX","description":"...","type":"...","impact":"...","effort":"..."}'
|
|
1038
|
+
|
|
1039
|
+
Then mark the relevant learnings as applied:
|
|
1040
|
+
curl -s -X PATCH http://localhost:${port}/evolution/learnings/LRN-XXX/apply -H 'Content-Type: application/json' -d '{"appliedTo":"EVO-XXX"}'
|
|
1041
|
+
|
|
1042
|
+
Also update MEMORY.md with any patterns worth preserving long-term.
|
|
1043
|
+
|
|
1044
|
+
If no actionable patterns found, exit silently.`,
|
|
1045
|
+
},
|
|
1046
|
+
tags: ['coherence', 'default', 'evolution'],
|
|
1047
|
+
},
|
|
1048
|
+
{
|
|
1049
|
+
slug: 'commitment-check',
|
|
1050
|
+
name: 'Commitment Check',
|
|
1051
|
+
description: 'Track action items and commitments. Surface overdue items and stale commitments.',
|
|
1052
|
+
schedule: '0 */4 * * *',
|
|
1053
|
+
priority: 'low',
|
|
1054
|
+
expectedDurationMinutes: 2,
|
|
1055
|
+
model: 'haiku',
|
|
1056
|
+
enabled: true,
|
|
1057
|
+
gate: `curl -sf http://localhost:${port}/evolution/actions/overdue 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); exit(0 if len(d.get('overdue',[])) > 0 else 1)"`,
|
|
1058
|
+
execute: {
|
|
1059
|
+
type: 'prompt',
|
|
1060
|
+
value: `Check for overdue commitments: curl -s http://localhost:${port}/evolution/actions/overdue
|
|
1061
|
+
|
|
1062
|
+
For each overdue action:
|
|
1063
|
+
1. Assess: Can this be completed now? Is it still relevant?
|
|
1064
|
+
2. If actionable, attempt to complete it or advance it
|
|
1065
|
+
3. If no longer relevant, cancel it: curl -s -X PATCH http://localhost:${port}/evolution/actions/ACT-XXX -H 'Content-Type: application/json' -d '{"status":"cancelled","resolution":"No longer relevant because..."}'
|
|
1066
|
+
4. If blocked, escalate to the user via Telegram (if configured)
|
|
1067
|
+
|
|
1068
|
+
Also check pending actions (curl -s http://localhost:${port}/evolution/actions?status=pending) for items that have been pending more than 48 hours without a due date — these are forgotten commitments.
|
|
1069
|
+
|
|
1070
|
+
If no overdue or stale items, exit silently.`,
|
|
1071
|
+
},
|
|
1072
|
+
tags: ['coherence', 'default', 'evolution'],
|
|
1073
|
+
},
|
|
730
1074
|
];
|
|
731
1075
|
}
|
|
732
1076
|
/**
|
|
@@ -915,6 +1259,33 @@ curl -s -X POST http://localhost:${port}/feedback \\
|
|
|
915
1259
|
Types: \`bug\`, \`feature\`, \`improvement\`, \`question\`
|
|
916
1260
|
|
|
917
1261
|
**Do not wait for the user to notice.** If a hook throws an error, report it. If a job fails, report it. If the server returns unexpected data, report it. You are not just using instar — you are part of its immune system.
|
|
1262
|
+
`);
|
|
1263
|
+
}
|
|
1264
|
+
// Check for Evolution System section
|
|
1265
|
+
if (!content.includes('Evolution System')) {
|
|
1266
|
+
additions.push(`
|
|
1267
|
+
### Evolution System
|
|
1268
|
+
|
|
1269
|
+
You have a built-in evolution system with four subsystems that track your growth.
|
|
1270
|
+
|
|
1271
|
+
**Evolution Queue** — Staged self-improvement proposals.
|
|
1272
|
+
- View: \`curl http://localhost:${port}/evolution/proposals\`
|
|
1273
|
+
- Propose: \`/evolve\` skill or \`POST /evolution/proposals\`
|
|
1274
|
+
|
|
1275
|
+
**Learning Registry** — Structured, searchable insights.
|
|
1276
|
+
- View: \`curl http://localhost:${port}/evolution/learnings\`
|
|
1277
|
+
- Record: \`/learn\` skill or \`POST /evolution/learnings\`
|
|
1278
|
+
|
|
1279
|
+
**Capability Gaps** — Track what you're missing.
|
|
1280
|
+
- View: \`curl http://localhost:${port}/evolution/gaps\`
|
|
1281
|
+
- Report: \`/gaps\` skill or \`POST /evolution/gaps\`
|
|
1282
|
+
|
|
1283
|
+
**Action Queue** — Commitments with follow-through tracking.
|
|
1284
|
+
- View: \`curl http://localhost:${port}/evolution/actions\`
|
|
1285
|
+
- Create: \`/commit-action\` skill or \`POST /evolution/actions\`
|
|
1286
|
+
|
|
1287
|
+
**Dashboard**: \`curl http://localhost:${port}/evolution\`
|
|
1288
|
+
**Skills**: \`/evolve\`, \`/learn\`, \`/gaps\`, \`/commit-action\`
|
|
918
1289
|
`);
|
|
919
1290
|
}
|
|
920
1291
|
// Check for Telegram Relay section (add if Telegram is configured)
|
|
@@ -965,6 +1336,15 @@ fi
|
|
|
965
1336
|
# For startup/resume/clear — output a compact orientation
|
|
966
1337
|
echo "=== SESSION START ==="
|
|
967
1338
|
|
|
1339
|
+
# Telegram-spawned session awareness
|
|
1340
|
+
# When auto-created for a Telegram topic, prime the agent to respond immediately
|
|
1341
|
+
if [ -n "\$INSTAR_TELEGRAM_TOPIC" ]; then
|
|
1342
|
+
echo ""
|
|
1343
|
+
echo "This session was auto-spawned for Telegram topic \$INSTAR_TELEGRAM_TOPIC."
|
|
1344
|
+
echo "A message from your user triggered this session and will arrive momentarily."
|
|
1345
|
+
echo "IMMEDIATELY acknowledge it via your Telegram relay — they are waiting."
|
|
1346
|
+
fi
|
|
1347
|
+
|
|
968
1348
|
# Identity summary (first 20 lines of AGENT.md — enough for name + role)
|
|
969
1349
|
if [ -f "$INSTAR_DIR/AGENT.md" ]; then
|
|
970
1350
|
echo ""
|
|
@@ -1174,6 +1554,55 @@ process.stdin.on('end', () => {
|
|
|
1174
1554
|
} catch { /* don't break on errors */ }
|
|
1175
1555
|
process.exit(0);
|
|
1176
1556
|
});
|
|
1557
|
+
`, { mode: 0o755 });
|
|
1558
|
+
// Post-action reflection — injects evolution awareness after significant actions.
|
|
1559
|
+
// PreToolUse hook for Bash. When the agent is about to send a response or commit,
|
|
1560
|
+
// it reminds them to consider what they learned. Advisory, not blocking.
|
|
1561
|
+
fs.writeFileSync(path.join(hooksDir, 'post-action-reflection.js'), `#!/usr/bin/env node
|
|
1562
|
+
// Post-action reflection — evolution awareness after significant actions.
|
|
1563
|
+
// PreToolUse hook for Bash. When the agent is about to commit, deploy, or
|
|
1564
|
+
// complete a task, injects a brief reminder to capture learnings.
|
|
1565
|
+
//
|
|
1566
|
+
// "Every action is an opportunity to learn. Most of that learning is lost
|
|
1567
|
+
// because nobody paused to ask: what did this teach me?"
|
|
1568
|
+
|
|
1569
|
+
let data = '';
|
|
1570
|
+
process.stdin.on('data', chunk => data += chunk);
|
|
1571
|
+
process.stdin.on('end', () => {
|
|
1572
|
+
try {
|
|
1573
|
+
const input = JSON.parse(data);
|
|
1574
|
+
if (input.tool_name !== 'Bash') process.exit(0);
|
|
1575
|
+
|
|
1576
|
+
const command = (input.tool_input || {}).command || '';
|
|
1577
|
+
if (!command) process.exit(0);
|
|
1578
|
+
|
|
1579
|
+
// Significant action patterns — moments worth reflecting on
|
|
1580
|
+
const significantPatterns = [
|
|
1581
|
+
/git\\s+commit/i,
|
|
1582
|
+
/git\\s+push/i,
|
|
1583
|
+
/npm\\s+publish/i,
|
|
1584
|
+
/curl\\s+-X\\s+POST.*\\/deploy/i,
|
|
1585
|
+
/instar\\s+server\\s+restart/i,
|
|
1586
|
+
];
|
|
1587
|
+
|
|
1588
|
+
if (!significantPatterns.some(p => p.test(command))) process.exit(0);
|
|
1589
|
+
|
|
1590
|
+
const reminder = [
|
|
1591
|
+
'POST-ACTION REFLECTION — Quick evolution check:',
|
|
1592
|
+
'',
|
|
1593
|
+
'Before moving on, consider:',
|
|
1594
|
+
'- Did this teach you something worth recording? → /learn',
|
|
1595
|
+
'- Did you notice a gap in your capabilities? → /gaps',
|
|
1596
|
+
'- Did you discover an improvement opportunity? → /evolve',
|
|
1597
|
+
'- Did you make a commitment to follow up? → /commit-action',
|
|
1598
|
+
'',
|
|
1599
|
+
'Skip if nothing notable. The value is in the pause, not the output.',
|
|
1600
|
+
].join('\\n');
|
|
1601
|
+
|
|
1602
|
+
process.stdout.write(JSON.stringify({ decision: 'approve', additionalContext: reminder }));
|
|
1603
|
+
} catch { /* don't break on errors */ }
|
|
1604
|
+
process.exit(0);
|
|
1605
|
+
});
|
|
1177
1606
|
`, { mode: 0o755 });
|
|
1178
1607
|
// External communication guard — ensures identity grounding before external posting.
|
|
1179
1608
|
// PreToolUse hook for Bash. Detects commands that post to external platforms.
|
|
@@ -1525,6 +1954,11 @@ function installClaudeSettings(projectDir) {
|
|
|
1525
1954
|
command: 'node .instar/hooks/external-communication-guard.js',
|
|
1526
1955
|
timeout: 5000,
|
|
1527
1956
|
},
|
|
1957
|
+
{
|
|
1958
|
+
type: 'command',
|
|
1959
|
+
command: 'node .instar/hooks/post-action-reflection.js',
|
|
1960
|
+
timeout: 5000,
|
|
1961
|
+
},
|
|
1528
1962
|
];
|
|
1529
1963
|
// PreToolUse: merge instar hooks into existing or create fresh
|
|
1530
1964
|
if (!hooks.PreToolUse) {
|
package/dist/commands/server.js
CHANGED
|
@@ -18,6 +18,8 @@ import { JobScheduler } from '../scheduler/JobScheduler.js';
|
|
|
18
18
|
import { AgentServer } from '../server/AgentServer.js';
|
|
19
19
|
import { TelegramAdapter } from '../messaging/TelegramAdapter.js';
|
|
20
20
|
import { RelationshipManager } from '../core/RelationshipManager.js';
|
|
21
|
+
import { ClaudeCliIntelligenceProvider } from '../core/ClaudeCliIntelligenceProvider.js';
|
|
22
|
+
import { AnthropicIntelligenceProvider } from '../core/AnthropicIntelligenceProvider.js';
|
|
21
23
|
import { FeedbackManager } from '../core/FeedbackManager.js';
|
|
22
24
|
import { DispatchManager } from '../core/DispatchManager.js';
|
|
23
25
|
import { UpdateChecker } from '../core/UpdateChecker.js';
|
|
@@ -25,6 +27,7 @@ import { registerPort, unregisterPort, startHeartbeat } from '../core/PortRegist
|
|
|
25
27
|
import { TelegraphService } from '../publishing/TelegraphService.js';
|
|
26
28
|
import { PrivateViewer } from '../publishing/PrivateViewer.js';
|
|
27
29
|
import { TunnelManager } from '../tunnel/TunnelManager.js';
|
|
30
|
+
import { EvolutionManager } from '../core/EvolutionManager.js';
|
|
28
31
|
/**
|
|
29
32
|
* Respawn a session for a topic, including thread history in the bootstrap.
|
|
30
33
|
* This prevents "thread drift" where respawned sessions lose context.
|
|
@@ -218,9 +221,9 @@ function wireTelegramRouting(telegram, sessionManager) {
|
|
|
218
221
|
const ctxPath = path.join(tmpDir, `ctx-${topicId}-${Date.now()}.txt`);
|
|
219
222
|
fs.writeFileSync(ctxPath, contextLines.join('\n'));
|
|
220
223
|
const bootstrapMessage = `[telegram:${topicId}] ${text} (IMPORTANT: Read ${ctxPath} for Telegram relay instructions — you MUST relay your response back.)`;
|
|
221
|
-
sessionManager.spawnInteractiveSession(bootstrapMessage, storedName).then((newSessionName) => {
|
|
224
|
+
sessionManager.spawnInteractiveSession(bootstrapMessage, storedName, { telegramTopicId: topicId }).then((newSessionName) => {
|
|
222
225
|
telegram.registerTopicSession(topicId, newSessionName);
|
|
223
|
-
telegram.sendToTopic(topicId, `Session
|
|
226
|
+
telegram.sendToTopic(topicId, `Session starting up — reading your message now. One moment.`).catch(() => { });
|
|
224
227
|
console.log(`[telegram→session] Auto-spawned "${newSessionName}" for topic ${topicId}`);
|
|
225
228
|
}).catch((err) => {
|
|
226
229
|
console.error(`[telegram→session] Auto-spawn failed:`, err);
|
|
@@ -351,8 +354,32 @@ export async function startServer(options) {
|
|
|
351
354
|
const sessionManager = new SessionManager(config.sessions, state);
|
|
352
355
|
let relationships;
|
|
353
356
|
if (config.relationships) {
|
|
357
|
+
// Wire LLM intelligence for identity resolution.
|
|
358
|
+
// Priority: Claude CLI (subscription, zero extra cost) > Anthropic API (explicit opt-in only)
|
|
359
|
+
const claudePath = config.sessions.claudePath;
|
|
360
|
+
let intelligenceMode = 'heuristic-only';
|
|
361
|
+
// Check if user explicitly opted into API-based intelligence
|
|
362
|
+
// (intelligenceProvider is a config-file-only field, not in the TypeScript type)
|
|
363
|
+
const explicitProvider = config.relationships.intelligenceProvider;
|
|
364
|
+
if (explicitProvider === 'anthropic-api') {
|
|
365
|
+
// User explicitly chose API — respect their decision
|
|
366
|
+
const apiProvider = AnthropicIntelligenceProvider.fromEnv();
|
|
367
|
+
if (apiProvider) {
|
|
368
|
+
config.relationships.intelligence = apiProvider;
|
|
369
|
+
intelligenceMode = 'LLM-supervised (Anthropic API — user choice)';
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
console.log(pc.yellow(' intelligenceProvider: "anthropic-api" set but ANTHROPIC_API_KEY not found'));
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
else if (claudePath) {
|
|
376
|
+
// Default: use Claude CLI via subscription (zero extra cost)
|
|
377
|
+
config.relationships.intelligence = new ClaudeCliIntelligenceProvider(claudePath);
|
|
378
|
+
intelligenceMode = 'LLM-supervised (Claude CLI subscription)';
|
|
379
|
+
}
|
|
354
380
|
relationships = new RelationshipManager(config.relationships);
|
|
355
|
-
|
|
381
|
+
const count = relationships.getAll().length;
|
|
382
|
+
console.log(pc.green(` Relationships loaded: ${count} tracked (${intelligenceMode})`));
|
|
356
383
|
}
|
|
357
384
|
let scheduler;
|
|
358
385
|
if (config.scheduler.enabled) {
|
|
@@ -454,7 +481,13 @@ export async function startServer(options) {
|
|
|
454
481
|
stateDir: config.stateDir,
|
|
455
482
|
});
|
|
456
483
|
}
|
|
457
|
-
|
|
484
|
+
// Set up evolution system (always enabled — the feedback loop infrastructure)
|
|
485
|
+
const evolution = new EvolutionManager({
|
|
486
|
+
stateDir: config.stateDir,
|
|
487
|
+
...(config.evolution || {}),
|
|
488
|
+
});
|
|
489
|
+
console.log(pc.green(' Evolution system enabled'));
|
|
490
|
+
const server = new AgentServer({ config, sessionManager, state, scheduler, telegram, relationships, feedback, dispatches, updateChecker, publisher, viewer, tunnel, evolution });
|
|
458
491
|
await server.start();
|
|
459
492
|
// Start tunnel AFTER server is listening
|
|
460
493
|
if (tunnel) {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AnthropicIntelligenceProvider — OPTIONAL IntelligenceProvider using the Anthropic Messages API.
|
|
3
|
+
*
|
|
4
|
+
* ⚠️ This provider uses API tokens (extra cost). For most Instar agents, the
|
|
5
|
+
* ClaudeCliIntelligenceProvider (which uses the Claude subscription) is the
|
|
6
|
+
* correct default. Only use this provider when:
|
|
7
|
+
* - The user explicitly sets intelligenceProvider: "anthropic-api" in config
|
|
8
|
+
* - The Claude CLI is not available
|
|
9
|
+
* - The user has a specific reason to prefer direct API access
|
|
10
|
+
*
|
|
11
|
+
* No SDK dependency — direct fetch calls, following the TelegramAdapter pattern.
|
|
12
|
+
*/
|
|
13
|
+
import type { IntelligenceProvider, IntelligenceOptions } from './types.js';
|
|
14
|
+
export declare class AnthropicIntelligenceProvider implements IntelligenceProvider {
|
|
15
|
+
private apiKey;
|
|
16
|
+
constructor(apiKey: string);
|
|
17
|
+
/**
|
|
18
|
+
* Create a provider from environment variables, or null if no key available.
|
|
19
|
+
* Follows the same graceful degradation pattern as TelegramAdapter's voice providers.
|
|
20
|
+
*/
|
|
21
|
+
static fromEnv(): AnthropicIntelligenceProvider | null;
|
|
22
|
+
evaluate(prompt: string, options?: IntelligenceOptions): Promise<string>;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=AnthropicIntelligenceProvider.d.ts.map
|