@josephyoung/pi-file-reference 0.1.1 → 0.1.2

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.
@@ -0,0 +1,29 @@
1
+ name: Publish to npm
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ paths:
8
+ - package.json
9
+ workflow_dispatch:
10
+
11
+ jobs:
12
+ publish:
13
+ runs-on: ubuntu-latest
14
+ permissions:
15
+ contents: read
16
+ id-token: write
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+ - uses: actions/setup-node@v4
20
+ with:
21
+ node-version: 24
22
+ - run: |
23
+ PACKAGE_VERSION=$(node -p "require('./package.json').version")
24
+ PUBLISHED_VERSION=$(npm view @josephyoung/pi-file-reference version 2>/dev/null || echo "0.0.0")
25
+ if [ "$PACKAGE_VERSION" != "$PUBLISHED_VERSION" ]; then
26
+ npm publish --provenance --access public
27
+ else
28
+ echo "Version $PACKAGE_VERSION already published, skipping"
29
+ fi
package/AGENTS.md ADDED
@@ -0,0 +1,47 @@
1
+ # pi-file-reference
2
+
3
+ Pi extension that resolves `@filepath` references in AGENTS.md and injects file content into system prompt.
4
+
5
+ ## Structure
6
+
7
+ - `extensions/index.ts` — extension entry point
8
+ - `session_start`: scan AGENTS.md for @refs, read files, cache in memory
9
+ - `before_agent_start`: inject cached file content into system prompt
10
+ - `package.json` — pi package metadata
11
+
12
+ ## How it works
13
+
14
+ When a user writes `@./docs/style-guide.md` in their AGENTS.md:
15
+
16
+ 1. The extension finds all `@` references in AGENTS.md (cwd or ~/.pi/agent/)
17
+ 2. Resolves paths (relative, absolute, ~/ expansion)
18
+ 3. If the path is a file: reads it
19
+ If the path is a directory: reads all immediate files (depth 1, sorted alphabetically)
20
+ 4. Injects them into the system prompt under `# Context References`
21
+
22
+ ## Conventions
23
+
24
+ - All code and comments in English
25
+ - AGENTS.md drives the project-level AI context
26
+ - Match Pi's internal style for context file injection (`## @path\n\n{content}`)
27
+
28
+ ## Publishing
29
+
30
+ After functional changes are committed and pushed, update the GitHub repo description if the feature set changed:
31
+
32
+ ```bash
33
+ gh repo edit --description "Pi extension: ..."
34
+ ```
35
+
36
+ Then bump version and push:
37
+
38
+ ```bash
39
+ npm version patch # bump version, creates commit + tag
40
+ git push origin main --tags # push to main triggers CI (package.json change)
41
+ ```
42
+
43
+ - GitHub Actions workflow: `.github/workflows/publish.yml`
44
+ - Trigger: push to main when `package.json` changes, or `workflow_dispatch`
45
+ - CI checks if version > npm latest before publishing (idempotent)
46
+ - Uses npm Trusted Publishing (OIDC) — no tokens or OTP needed
47
+ - OIDC runs on `refs/heads/main` — ensure npm Trusted Publisher is configured for branch `main`
package/README.md CHANGED
@@ -21,6 +21,16 @@ A [pi](https://github.com/earendil-works/pi-coding-agent) extension that resolve
21
21
 
22
22
  The `@` must be at the start of a line or preceded by whitespace.
23
23
 
24
+ ### Directory references
25
+
26
+ When `@path` resolves to a directory, all immediate files (depth 1) are injected:
27
+
28
+ ```
29
+ @./docs
30
+ ```
31
+
32
+ Injects `@docs/style-guide.md`, `@docs/patterns.md`, etc. (sorted alphabetically). Subdirectories are skipped. Trailing `/` is stripped (`@./docs/` works the same).
33
+
24
34
  ## Installation
25
35
 
26
36
  ```bash
@@ -122,14 +122,41 @@ function loadRefs(cwd: string): RefContent[] {
122
122
  return true;
123
123
  });
124
124
 
125
- // Read each referenced file
125
+ // Read each referenced file or directory
126
126
  const results: RefContent[] = [];
127
127
  for (const ref of uniqueRefs) {
128
- const resolvedPath = resolveRef(ref, baseDir);
129
- if (fs.existsSync(resolvedPath)) {
130
- results.push({ ref, content: fs.readFileSync(resolvedPath, "utf-8") });
128
+ // Strip trailing slashes for consistent handling
129
+ const cleanRef = ref.endsWith("/") ? ref.slice(0, -1) : ref;
130
+ const resolvedPath = resolveRef(cleanRef, baseDir);
131
+
132
+ if (!fs.existsSync(resolvedPath)) {
133
+ console.warn(`[pi-file-reference] @${cleanRef} -> ${resolvedPath} not found, skipping`);
134
+ continue;
135
+ }
136
+
137
+ const stat = fs.statSync(resolvedPath);
138
+ if (stat.isDirectory()) {
139
+ // Read all files at depth 1, skip subdirectories
140
+ const entries = fs.readdirSync(resolvedPath, { withFileTypes: true });
141
+ const files = entries
142
+ .filter((e) => e.isFile())
143
+ .map((e) => e.name)
144
+ .sort(); // deterministic order
145
+
146
+ if (files.length === 0) {
147
+ console.warn(`[pi-file-reference] @${cleanRef} is an empty directory, skipping`);
148
+ continue;
149
+ }
150
+
151
+ for (const fileName of files) {
152
+ const filePath = path.join(resolvedPath, fileName);
153
+ results.push({
154
+ ref: `${cleanRef}/${fileName}`,
155
+ content: fs.readFileSync(filePath, "utf-8"),
156
+ });
157
+ }
131
158
  } else {
132
- console.warn(`[pi-file-reference] @${ref} -> ${resolvedPath} not found, skipping`);
159
+ results.push({ ref: cleanRef, content: fs.readFileSync(resolvedPath, "utf-8") });
133
160
  }
134
161
  }
135
162
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@josephyoung/pi-file-reference",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "private": false,
5
5
  "description": "Pi extension that resolves @filepath references in AGENTS.md and injects file content into system prompt",
6
6
  "type": "module",