poly-agent 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -90,7 +90,7 @@ async function runInit() {
90
90
  cancel('Operation cancelled.');
91
91
  process.exit(0);
92
92
  }
93
- // Step 4: Copy files
93
+ // Step 4: Install prompts with shared instructions
94
94
  const targetDir = IDE_DIRECTORIES[selectedIDE];
95
95
  const fullTargetPath = path.join(process.cwd(), targetDir);
96
96
  const s = spinner();
@@ -98,9 +98,16 @@ async function runInit() {
98
98
  try {
99
99
  // Create target directory if it doesn't exist
100
100
  await fs.mkdir(fullTargetPath, { recursive: true });
101
- // Copy each selected prompt file
102
- const copyPromises = selectedPrompts.map(async (filename) => {
103
- const sourcePath = path.join(promptsDir, filename);
101
+ // Install each selected prompt with shared instructions injected
102
+ const installPromises = selectedPrompts.map(async (filename) => {
103
+ // Load prompt with shared instructions injected
104
+ const prompt = await loader.loadPrompt(filename);
105
+ // Reconstruct the full file content with frontmatter
106
+ const fullContent = `---
107
+ name: ${prompt.name}
108
+ description: ${prompt.description}
109
+ ---
110
+ ${prompt.content}`;
104
111
  if (selectedIDE === 'Claude') {
105
112
  // For Claude, create a folder with the prompt name and SKILL.md inside
106
113
  const promptName = path.basename(filename, '.md');
@@ -108,23 +115,23 @@ async function runInit() {
108
115
  const skillFilePath = path.join(skillFolderPath, 'SKILL.md');
109
116
  // Create the skill folder
110
117
  await fs.mkdir(skillFolderPath, { recursive: true });
111
- // Copy the content to SKILL.md
112
- await fs.copyFile(sourcePath, skillFilePath);
118
+ // Write the processed content to SKILL.md
119
+ await fs.writeFile(skillFilePath, fullContent, 'utf-8');
113
120
  return `${promptName}/SKILL.md`;
114
121
  }
115
122
  else {
116
- // For other IDEs, copy directly
123
+ // For other IDEs, write directly
117
124
  const targetPath = path.join(fullTargetPath, filename);
118
- await fs.copyFile(sourcePath, targetPath);
125
+ await fs.writeFile(targetPath, fullContent, 'utf-8');
119
126
  return filename;
120
127
  }
121
128
  });
122
- const copiedFiles = await Promise.all(copyPromises);
123
- s.stop(`✓ Installed ${copiedFiles.length} prompt(s) successfully`);
129
+ const installedFiles = await Promise.all(installPromises);
130
+ s.stop(`✓ Installed ${installedFiles.length} prompt(s) successfully`);
124
131
  // Success message
125
132
  log.success(`Prompts installed to: ${targetDir}`);
126
133
  log.info(`Installed files:`);
127
- copiedFiles.forEach(file => {
134
+ installedFiles.forEach(file => {
128
135
  log.info(` - ${file}`);
129
136
  });
130
137
  outro('Installation complete! 🎉');
@@ -2,9 +2,60 @@ import fs from 'fs/promises';
2
2
  import path from 'path';
3
3
  export class PromptLoader {
4
4
  promptsDir;
5
+ sharedInstructionsCache = null;
5
6
  constructor(promptsDir) {
6
7
  this.promptsDir = promptsDir;
7
8
  }
9
+ /**
10
+ * Load all shared instructions from the _shared directory.
11
+ * These will be appended to every prompt.
12
+ */
13
+ async loadSharedInstructions() {
14
+ // Return cached instructions if available
15
+ if (this.sharedInstructionsCache !== null) {
16
+ return this.sharedInstructionsCache;
17
+ }
18
+ const sharedDir = path.join(this.promptsDir, '_shared');
19
+ const instructions = [];
20
+ try {
21
+ const files = await fs.readdir(sharedDir);
22
+ const mdFiles = files.filter(f => f.endsWith('.md'));
23
+ for (const file of mdFiles) {
24
+ const filePath = path.join(sharedDir, file);
25
+ const fileContent = await fs.readFile(filePath, 'utf-8');
26
+ // Parse frontmatter to get name, extract content
27
+ const frontmatterRegex = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
28
+ const match = fileContent.match(frontmatterRegex);
29
+ if (match) {
30
+ const metadata = this.parseFrontmatter(match[1]);
31
+ instructions.push({
32
+ name: metadata.name || path.basename(file, '.md'),
33
+ content: match[2].trim()
34
+ });
35
+ }
36
+ else {
37
+ // No frontmatter, use entire content
38
+ instructions.push({
39
+ name: path.basename(file, '.md'),
40
+ content: fileContent.trim()
41
+ });
42
+ }
43
+ }
44
+ }
45
+ catch (error) {
46
+ // _shared directory doesn't exist or is empty - that's okay
47
+ // Return empty array, shared instructions are optional
48
+ }
49
+ this.sharedInstructionsCache = instructions;
50
+ return instructions;
51
+ }
52
+ /**
53
+ * Clear the shared instructions cache.
54
+ * Useful if shared instructions are modified at runtime.
55
+ */
56
+ clearCache() {
57
+ this.sharedInstructionsCache = null;
58
+ }
8
59
  async loadPrompt(filename, variables = {}) {
9
60
  const filePath = path.join(this.promptsDir, filename);
10
61
  try {
@@ -12,22 +63,33 @@ export class PromptLoader {
12
63
  // Basic Frontmatter parsing
13
64
  const frontmatterRegex = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
14
65
  const match = fileContent.match(frontmatterRegex);
66
+ let name;
67
+ let description;
68
+ let content;
15
69
  if (!match) {
16
70
  // Fallback if no frontmatter
17
- return {
18
- name: path.basename(filename, '.md'),
19
- description: 'No description provided.',
20
- content: this.injectVariables(fileContent, variables)
21
- };
71
+ name = path.basename(filename, '.md');
72
+ description = 'No description provided.';
73
+ content = fileContent;
74
+ }
75
+ else {
76
+ const rawFrontmatter = match[1];
77
+ const metadata = this.parseFrontmatter(rawFrontmatter);
78
+ name = metadata.name || path.basename(filename, '.md');
79
+ description = metadata.description || '';
80
+ content = match[2];
81
+ }
82
+ // Inject variables
83
+ content = this.injectVariables(content, variables);
84
+ // Append shared instructions
85
+ const sharedInstructions = await this.loadSharedInstructions();
86
+ if (sharedInstructions.length > 0) {
87
+ const sharedContent = sharedInstructions
88
+ .map(inst => `\n---\n\n${inst.content}`)
89
+ .join('\n');
90
+ content = content + sharedContent;
22
91
  }
23
- const rawFrontmatter = match[1];
24
- const content = match[2];
25
- const metadata = this.parseFrontmatter(rawFrontmatter);
26
- return {
27
- name: metadata.name || path.basename(filename, '.md'),
28
- description: metadata.description || '',
29
- content: this.injectVariables(content, variables)
30
- };
92
+ return { name, description, content };
31
93
  }
32
94
  catch (error) {
33
95
  throw new Error(`Failed to load prompt ${filename}: ${error}`);
@@ -55,7 +117,8 @@ export class PromptLoader {
55
117
  async listPrompts() {
56
118
  try {
57
119
  const files = await fs.readdir(this.promptsDir);
58
- return files.filter(f => f.endsWith('.md'));
120
+ // Filter out _shared directory and only return .md files
121
+ return files.filter(f => f.endsWith('.md') && !f.startsWith('_'));
59
122
  }
60
123
  catch (error) {
61
124
  return [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "poly-agent",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "CLI installer for AI IDE prompts - install commands, skills, and workflows for Cursor, ClaudeCode, and Antigravity",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -0,0 +1,103 @@
1
+ ---
2
+ name: Context Hook
3
+ description: Shared instructions for automatic context dumping after file edits.
4
+ type: shared
5
+ ---
6
+
7
+ # Context Management Hook
8
+
9
+ ## Behavior
10
+
11
+ After **every file edit** you make, you MUST update the project context file. This ensures continuity across conversations and helps maintain a clear record of progress.
12
+
13
+ ## When to Update Context
14
+
15
+ 1. **After any file edit** - Immediately after modifying, creating, or deleting a file
16
+ 2. **When the task context changes** - New goals, pivots, or scope changes
17
+ 3. **When explicitly mentioned** - If the user references `.context/` or asks about context
18
+ 4. **At conversation milestones** - Completing a feature, fixing a bug, reaching a checkpoint
19
+
20
+ ## Context File Location & Naming
21
+
22
+ - **Directory**: `.context/`
23
+ - **Filename**: Generate a short, descriptive kebab-case name based on the current task
24
+ - Examples: `feature-auth.md`, `bugfix-api-timeout.md`, `refactor-database-layer.md`, `setup-ci-pipeline.md`
25
+ - **Persistence**: Use the SAME context file throughout a conversation/task. Only create a new one if the task fundamentally changes.
26
+
27
+ ## Context File Format
28
+
29
+ Use this exact structure:
30
+
31
+ ```markdown
32
+ ---
33
+ created: [ISO timestamp when first created]
34
+ updated: [ISO timestamp of last update]
35
+ task: [One-line task description]
36
+ status: [in-progress | completed | blocked | paused]
37
+ ---
38
+
39
+ # Context: [short-name]
40
+
41
+ ## Summary
42
+ [2-3 sentence AI-generated summary of what this task is about and current state]
43
+
44
+ ## Files Changed
45
+ - `path/to/file.ts` - [Brief description of change]
46
+ - `path/to/another.ts` - [Brief description of change]
47
+
48
+ ## Current Goals
49
+ 1. [Primary goal]
50
+ 2. [Secondary goal]
51
+ 3. [etc.]
52
+
53
+ ## Progress
54
+ - [x] [Completed item]
55
+ - [x] [Completed item]
56
+ - [ ] [Pending item]
57
+ - [ ] [Pending item]
58
+
59
+ ## Next Steps
60
+ - [Immediate next action]
61
+ - [Following action]
62
+
63
+ ## Notes
64
+ [Any important context, decisions made, blockers, or things to remember]
65
+ ```
66
+
67
+ ## Rules
68
+
69
+ 1. **Always update, never skip** - Even small edits warrant a context update
70
+ 2. **Be concise but complete** - Capture essential information without verbosity
71
+ 3. **Track ALL file changes** - Every file you touch should be listed
72
+ 4. **Maintain history** - Don't remove completed items from Progress, mark them done
73
+ 5. **Update timestamps** - Always update the `updated` field in frontmatter
74
+ 6. **Create directory if needed** - If `.context/` doesn't exist, create it
75
+
76
+ ## Example Workflow
77
+
78
+ 1. User asks: "Add authentication to the API"
79
+ 2. You create/update `.context/feature-api-auth.md` with initial goals
80
+ 3. You edit `src/auth/middleware.ts`
81
+ 4. You immediately update `.context/feature-api-auth.md` with the file change
82
+ 5. You edit `src/routes/login.ts`
83
+ 6. You update `.context/feature-api-auth.md` again
84
+ 7. Continue until task complete, then set status to `completed`
85
+
86
+ ## Recalling Context
87
+
88
+ When a user asks to recall or resume a context (e.g., "recall feature-auth", "continue from context X", "load context"):
89
+
90
+ 1. **Read ONLY the specified context file** from `.context/` - Do NOT scan the entire project
91
+ 2. **Trust the context file** - It contains all the information you need
92
+ 3. **Summarize the current state** - What was done, what remains
93
+ 4. **Confirm understanding** with the user before proceeding
94
+ 5. **Only read files listed in "Files Changed"** if you need to check current state
95
+ 6. **Continue updating** the same context file as you work
96
+
97
+ **IMPORTANT**: When recalling context, do NOT:
98
+ - Search or scan the entire codebase
99
+ - Read files not mentioned in the context
100
+ - Run broad exploratory searches
101
+ - Assume information beyond what's in the context file
102
+
103
+ If asked to **list contexts**, read the `.context/` directory and show available files with their status.
@@ -0,0 +1,82 @@
1
+ ---
2
+ name: Context Recall
3
+ description: Load and resume work from a saved context file.
4
+ ---
5
+ # Context Recall
6
+
7
+ You are being asked to **resume work** from a previously saved context.
8
+
9
+ ## Instructions
10
+
11
+ 1. **Read the context file** specified by the user (from `.context/` directory)
12
+ 2. **Understand the state** - Review the summary, files changed, goals, and progress
13
+ 3. **Identify next steps** - Look at what was marked as pending or in "Next Steps"
14
+ 4. **Resume seamlessly** - Continue the work as if you never left
15
+
16
+ ## How to Use
17
+
18
+ The user will provide one of:
19
+ - A context file name: `feature-auth` or `feature-auth.md`
20
+ - A full path: `.context/feature-auth.md`
21
+ - Or ask you to list available contexts
22
+
23
+ ## If Asked to List Contexts
24
+
25
+ Read the `.context/` directory and present available context files:
26
+
27
+ ```
28
+ Available contexts:
29
+ - feature-auth.md (updated: 2026-01-12)
30
+ - bugfix-api-timeout.md (updated: 2026-01-11)
31
+ - refactor-database.md (updated: 2026-01-10)
32
+ ```
33
+
34
+ ## After Loading Context
35
+
36
+ 1. **Summarize** what you understand about the task
37
+ 2. **Confirm** the current state and what remains to be done
38
+ 3. **Ask** if the user wants to continue from where it left off, or modify the approach
39
+ 4. **Continue updating** the same context file as you make changes
40
+
41
+ ## Example Interaction
42
+
43
+ **User**: "Recall context feature-auth"
44
+
45
+ **You**:
46
+ > I've loaded the context for **feature-auth**:
47
+ >
48
+ > **Summary**: Implementing JWT-based authentication for the API
49
+ >
50
+ > **Progress**:
51
+ > - ✅ Created auth middleware
52
+ > - ✅ Set up login route
53
+ > - ⏳ Token refresh logic (in progress)
54
+ > - ⬜ Rate limiting
55
+ >
56
+ > **Last worked on**: `src/auth/refresh.ts`
57
+ >
58
+ > Would you like me to continue with the token refresh logic, or would you prefer to work on something else?
59
+
60
+ ## Critical Rules
61
+
62
+ 1. **ONLY read the context file** - Do NOT scan the entire project or codebase
63
+ 2. **Trust the context file** - It contains everything you need to understand the task
64
+ 3. **Read files listed in "Files Changed"** - Only if you need to understand current state
65
+ 4. **Don't guess or make up content** - Only use information from the context file
66
+ 5. **If context file doesn't exist** - Inform the user and offer to create one
67
+ 6. **Keep the context file updated** - As you continue working
68
+
69
+ ## What NOT To Do
70
+
71
+ - ❌ Do NOT search the entire codebase to "understand the project"
72
+ - ❌ Do NOT read files that aren't mentioned in the context
73
+ - ❌ Do NOT run broad searches or scans
74
+ - ❌ Do NOT assume context beyond what's in the file
75
+
76
+ ## What TO Do
77
+
78
+ - ✅ Read ONLY `.context/[name].md` first
79
+ - ✅ Use the "Files Changed" section to know which files are relevant
80
+ - ✅ Read specific files from "Files Changed" if needed for current state
81
+ - ✅ Follow "Next Steps" from the context file
82
+ - ✅ Ask the user if anything is unclear