Reviewed GitHub issue and project context.
UnderstandDrafted consolidated comment with design decisions.
EditExpanded comment with detailed implementation instructions.
Edit>git statusAnalyze GitHub issue(s): https://github.com/badlogic/pi-mono/issues/645 this is an issue by me and you. we already went through all of this. i think its finally time to implement this garbage. analyze the issue and the codebase, tell me if you have any open questions so we can finalize the details, then go to town
For each issue:
Read the issue in full, including all comments and linked issues/PRs.
For bugs:
For feature requests:
Do NOT implement unless explicitly asked. Analyze and propose only.
Preparing to create GitHub issue
I'm focusing on drafting a GitHub issue to capture the user's concrete task without implementing or modifying the README, as per instructions. I'll view the current issue details for context.
>gh issue view 645 --json title,body,comments,labels,statePlanning parallel reading of linked issues and files
The plan is to fully read all comments and code in linked issues #326, #562, and #751, plus relevant files without offsets, using parallel reads to speed this up. Next, I'll sequence these operations using parallel calls to issue views and file reads.
>gh issue view 326 --json title,body,comments,labels,state>gh issue view 562 --json title,body,comments,labels,state>gh issue view 751 --json title,body,comments,labels,statePlanning full file reads for analysis
Resolving large file read conflict
The file exceeds 50KB, so to retrieve it fully I’ll read the remaining part using offsets despite instructions against offsets for full reads, since the size requires chunked reading. I’ll continue from line 1521 to get the complete file.
Continuing file read with offset
Proceeding to read the remaining agent-session file starting at offset 1521 without a limit, expecting to fetch additional segments if needed due to size.
Continuing file read at offset 1529
Continuing interactive mode implementation
Noting missing docs
Requesting remaining file content
Planning extension loader analysis
I'm preparing to read the extension loader code to understand how to extract it from the SDK per issue #645 and identify related implementation details. Next, I'll locate and inspect the loader file in the core extensions folder.
>ls /Users/badlogic/workspaces/pi-mono/packages/coding-agent/src/core/extensionsReviewing loader and types definitions
I'm reading loader.ts and types.ts fully to gather all necessary type definitions and understand their relationships for accurate typing and integration.
Analyzing package manager feature proposal
I'm outlining a design for a package manager with loader, reload, and watch features, identifying needed interface and main.ts changes plus runner reload support, while pinpointing open questions on settings storage, npm handling, and CLI integration. Next, I'll verify current extension loading and reload gaps by reviewing prompt templates and skills loading files.
Summarizing feature scope and open questions
I'm detailing #645 tasks covering package manager, loader, bootstrap flow, session reload, CLI commands, and watch mode, plus noting current extension/skill/prompt loading and absence of reload. I highlight unclear points on recursive skill discovery, compatibility with existing extension loading, settings merging semantics, npm install location, and theme loading, preparing precise questions for clarification.
Summarizing theme loading and extension management analysis
I've analyzed theme loading anchored by a custom themes directory and noted it would require new package-level loading support. The current extension loader focuses on local paths without package management. I'll outline the issue context, related tickets, current loader architecture, propose new PackageManager and Loader modules, and suggest CLI commands for package install/update/remove with options for organizing commands separately.
Detailing implementation approach and open questions
The current system lacks a unified loader abstraction, package manager, reload support, and CLI commands for package management. I propose creating a new core loader module to handle loading extensions, skills, prompts, themes, and context files from resolved paths with filtering, reusing existing extension loader logic where possible. A new PackageManager module would manage npm/git/local package sources and settings, handle installs/updates, and coordinate with SettingsManager for source persistence. Reload support would move initialization logic into AgentSession with a reload method triggering rebuilds of prompts, skills, and tools. Watch mode should gather relevant paths and run in interactive mode only.
Open questions include whether to install npm packages globally or in a local directory, how to migrate settings from paths to package sources, whether to retain automatic extension discovery alongside package manager resolution, how to handle overrides merging in SettingsManager, the scope of files and manifests the loader should handle (including SYSTEM.md and APPEND_SYSTEM.md), how and where to add CLI subcommands for install/remove/update, version pinning logic for git packages, and how to integrate new loaders with existing SDK/session runner initialization and event bus reuse. The response also notes affected files and the need for documentation updates.
Summary of issue #645 and linked items
Current code behavior
Concise implementation approach Phase 1: PackageManager
Phase 2: Loader
Phase 3: Bootstrap flow
Phase 4: Runner initializer and AgentSession reload
Phase 5: Reload and watch
Phase 6: Package management CLI
Affected files and changes needed
Open questions to finalize
If these are confirmed, I can move to implementation.
Extend the pi manifest handling to include prompts and themes and maybe context file paths. Current PiManifest includes skills and themes but loader only uses extensions. Add prompts and context entries to the manifest shape.
i think this also needs some talking about
Providing example and clarifications on settings and manifest
I'm preparing a concise example showing how local settings.json merges with system and appends for point 4. I'll outline that the manifest includes entries for prompts, themes, skills, and context, clarifying that the pi field controls priority or inclusion. I'll also confirm skill recursion is handled and raise an open question about default behavior for auto-discovery and settings merging, noting that watch mode applies in all cases.
Answers and details
Project .pi/settings.json: { "extensions": ["./project-ext"], "skills": { "includeSkills": ["docker-*"] } }
With current deep merge behavior, arrays override, not merge. Effective: extensions: ["./project-ext"] skills.includeSkills: ["docker-*"]
If you want additive merge for extensions, we need custom handling so project extensions are appended to global instead of replacing. Same question applies to skills includeSkills and ignoredSkills. Do you want additive merge or override for each array.
If loader owns it: Option A. Keep current behavior
Option B. Loader returns explicit prompt overrides
Option C. Hybrid
Given your note, Option A or C is minimal. Option B is a more complete centralization but adds more decisions to loader.
Skills recursion Yes. Current loadSkills searches ~/.pi/agent/skills and /.pi/skills recursively already. It also loads Codex and Claude locations with their specific formats.
Git update I will implement: if source has tag or commit, skip update when already at that ref. If no version, update to latest.
Manifest handling discussion Today PiManifest in extensions/loader.ts only checks pi.extensions, but the interface already includes themes and skills. It does not include prompts or context files.
We need to decide what pi field means for non extensions. Proposed options:
Option 1. pi field means explicit paths only, no auto discovery inside the package
Option 2. pi field is an augmentation, not a replacement
Option 3. pi field only for extensions, other types always use auto discovery
Given your earlier issue text, it sounds like Option 1 is intended. If no pi field, fall back to default discovery for extensions, skills, prompts, themes. If pi field exists, use only those entries.
Also need to decide path formats:
Open questions
Once you confirm, I will proceed to implementation.
as for merging extensions arrays, yeah that makes sense, merge local and global, warn on conflicts (same extension different version via npm or git for example).
what about themes and prompt templates?
that can stay as is, packaged extensions won't ship SYSTEM.md or AGENTS.md or APPEND_SYSTEM.md. that said, wouldn't it make sense to construct the system in such a way that the loader is responsible for ingesting and providing all the dynamic parts? extensions, skills, themes, prompt templates, AGENTS.md, APPEND_SYSTEM.md, SYSTEM.md? the default loader would just implement the current behaviour of looking in the default locations. A custom loader can provide those things whichever way it likes, no? Then main uses the default loader and passes that to createAgentSession in the SDK?
So i think that's also part of what the default loader will do. resolve skills in known locations, resolve skills from extension packages, provide them all as a nice list of SKILL.md files to load to createAgentSession?
approved
manifest handling i don't think we should include context files in manifests, but we must include prompts.
pi field means explicit paths only (either folders to which parts of auto-disocvery applies, or concrete files), full auto-discovery (like we do in ~/.pi/agent) only for extension packages without a pi field. those must then follow the folder and file layouts expected in ~/.pi/agent
path formats:
Is this consistent? got a better proposal?
open questions:
let's keep discussing based on the above, possibly give feedback and a proposal of the full thing
Proposing SDK loader and settings changes
I’ll clarify the SKILL.md vs SKILLS.md mismatch by standardizing on SKILL.md as the code uses that. For settings, only extension arrays merge with conflict warnings; themes and prompts don’t have array settings currently. Skills settings will remove include/ignored filters. I propose a new Loader interface returning a load result that includes discovered extensions, skills, prompts, themes, context files, and system prompt files, used as input to createAgentSession via options for preloaded data. The default loader will handle discovery as now. SettingsManager and the settings schema need updates to reflect skill settings removing include/ignored. For merging, extensions arrays merge locally and globally with warnings on conflicts; we should consider merging extension sources from the CLI with similar warnings. Custom skill directories remain and should merge additively with warnings on duplicates since filtering is removed. This balanced approach avoids ambiguous merges and improves extensibility.
Confirming manifest support and naming consistency
I’ll note that prompts and themes support manifests as files or directories with rules, with themes and prompts loaded globally and non-recursively for listing and application. I’ll confirm consistently using SKILL.md (not SKILLS.md) and suggest minor settings tweaks to align with these standards.
Notes and proposal based on your latest guidance
Clarification needed
Settings merge and removal of skill filters
Extensions array merging and conflicts
Themes and prompt templates in settings
Loader ownership of all dynamic parts This fits well. I suggest we formalize a Loader result that includes:
Default loader behavior
Custom loader behavior
SDK changes
Manifest handling proposal
Path formats based on your list This is consistent, with one change for naming.
If you want prompts or themes to be recursive within package manifests, say so. Otherwise I will keep non recursive to match the folder rules.
Open questions to finalize
Once these are locked, I can proceed to implementation.
A yes, SKILL.md
I want to get rid of the source flags. if people want to use skills from another harness, they should symlink or use customDirectories. i'm ok with this breaking change. Merging of global and project customDirectories with dedup is fine too. I have a feeling we won't need enabled. it's not used anywhere either afaikt! i.e. SettingsManager.getSkillsEnabled(). so that means skills can become a simple array like extensions as well? which references local files SKILL.md or folders (recursively find SKILL.mds), in addition to discovery in ~/.pi/agent/skills
themes and prompt templates, yes makes sense, tho i feel we should harmonize this with extensions and skills above? I kind of feel there's a general theme here we can apply to all 4 things: extensions, skills, prompts themes?
we auto-discovery in ~/.pi/agent and /.pi/
Then in addition to that auto discovery, settings.json can have
skills: ["folder", "file"] prompts: ["folder", "file"] themes: ["folder", "file"] extensions: ["folder", "file", "npm", "git"]
and the same rules as for auto-disovery apply? any skill, theme or prompt declared in an extension package (either by folder layout or via pi field in packages.json)
if people want to disable skills or extensions loading, they can use --no-skills and --no-extensions, no need to make the config super complicated
I think the loader should have getters to get the currently loaded extension runtimes, skill objects, prompttemplate objects, theme objects, contextFiles, systemPromptSource, and appendPromptSources
Loader then also has a reload() method that reloads all the things it was configured to load, subsequent getXXX() calls return the new objects. does that make sense?
the sdk then does ... nothing much. it just takes a loader instance which it binds to the AgentSession is creates, so the agent session can reload things at any time
so the loader really loads everything, including context files, system.md, etc. does that make sense? tui can also get access to the loader to set things up
new proposal
Proposing loader API with breaking change
I'm summarizing by proposing a concrete loader API design that includes a breaking change and asking for confirmation before implementation. The response avoids em dashes and remains concise.
Proposal aligned with your updated direction
Summary of behavior
Auto discovery rules
Paths listed in settings.json
Extension packages
Loader shape I propose a Loader interface like:
type LoaderConfig = { cwd: string; agentDir: string; settingsManager: SettingsManager; packageManager: PackageManager; filters?: { extensions?: { enabled?: boolean; include?: string[]; exclude?: string[] }; skills?: { enabled?: boolean }; prompts?: { enabled?: boolean }; themes?: { enabled?: boolean }; }; };
type LoadResult = { extensions: LoadExtensionsResult; skills: Skill[]; skillWarnings: SkillWarning[]; promptTemplates: PromptTemplate[]; themes: ThemeInfo[] | Theme[]; contextFiles: Array<{ path: string; content: string }>; systemPromptSource?: string; appendSystemPromptSource?: string; };
interface Loader { load(): Promise; getResult(): LoadResult | undefined; }
Notes
SDK changes
Questions to confirm
If this matches, I will proceed to implement exactly this shape.
that loader interface is fucking garbage.
i think what we need is something more like Resources interface
interface ResourceLoader { getExtensions(): ExtensionLoaderResult (prev LoadExtensionsResult) getSkills(): { skills: Skill[], warnings: SkillWarning[] } getPrompts(): { prompts: PromptTemplate[], warnings PromptTemplateWarning[] } getThemes(): { themes: Theme[], warnings: ThemeWarnings[] } getAgentsFiles(): { agentsFiles: { path: string, content: string }[] } getSystemPrompt(): string? getAppendSystemPrompt(): string[]? async reload(): ?? }
then we have a DefaultResourceLoader that implemnents our default semantics, people can subclass it, or wrap it?
and createAgentSession takes a ResourceLoader, and AgentSession exposes the ResourceLoader and has a reload() method that rewires everything, and possibly emits an event to tui or other parties when reloading has finished?
I want this to be as simple and clean as possible
Preparing concise revised proposal
I'm drafting a concise revised proposal that includes missing warning types and asks for clarifications while avoiding em dashes.
Understood. Here is a cleaner proposal aligned with your ResourceLoader shape.
Proposed interfaces
export interface ResourceLoader { getExtensions(): LoadExtensionsResult; getSkills(): { skills: Skill[]; warnings: SkillWarning[] }; getPrompts(): { prompts: PromptTemplate[]; warnings: PromptTemplateWarning[] }; getThemes(): { themes: Theme[]; warnings: ThemeWarning[] }; getAgentsFiles(): { agentsFiles: Array<{ path: string; content: string }> }; getSystemPrompt(): string | undefined; getAppendSystemPrompt(): string[]; // one or more fragments reload(): Promise<void>;}Notes
DefaultResourceLoader behavior
SDK and AgentSession changes
Open questions
If this is good, I will proceed and adjust the analysis for warnings types.
errors: Array<{ path: string; error: string }>
i think this shape is what we want for warnings/errors in general? maybe we just have warningsAndErrors, and add a type field "warning" | "error", an optional path (in case the resource wasn't laoded from disk), and a text: string?
Proposing warnings and errors format
I suggest a consistent shape for warnings and errors as objects with a code string and a message string. These should integrate into validation functions and UI feedback components. Please confirm this approach before I proceed.
Proposed unified diagnostics shape
export interface ResourceDiagnostic { type: "warning" | "error"; message: string; path?: string;}ResourceLoader getters return { data, diagnostics } for each resource type, or we add a single getDiagnostics that aggregates them.
Example per resource:
getSkills(): { skills: Skill[]; diagnostics: ResourceDiagnostic[] }This replaces skillWarnings and any future prompt or theme warnings.
Confirm if you want per resource diagnostics or one aggregated list.
DefaultResourceLoader behavior
note that we also have --extension and other cli flags that may add additional resources, no?
Confirming extension flags plan
I plan to extend the loader to accept extraPaths for extensions, skills, prompts, themes, and system prompt sources, appending from CLI input plus custom loader input. I'll ask for confirmation before proceeding.
Yes. DefaultResourceLoader should take CLI overrides too.
Proposal
For now only extensionSources and disable flags are used by CLI. This keeps it extensible without more CLI flags.
Confirm if you want CLI to also accept explicit prompt, theme, skill sources.
does shouldn't be overrides though, should they be? the string[] at least, no? those are in addition to the auto discovery shit?
Confirming additive semantics and discussion scope
Yes, the semantics are additive. I'll provide updated semantics and ask about --skills while keeping instructions not to implement but just discuss.
Agree. CLI lists should be additive.
Updated behavior
Confirm if you want --skills and --themes and --prompts flags to exist, or only extensions for now.
no aggreation, each getter returns diagnostics just for that resource tpe.
read @packages/coding-agent/src/cli/args.ts to see if we forgot something?
CLI args we need to update or remove
Proposal update for ResourceLoader + CLI
If you want to repurpose --skills to accept explicit paths, confirm and I will adjust parseArgs and help accordingly.
so, we already have --extension, i think we should have --skill (takes a SKILL.md) --theme (takes a theme.json) --prompt-template (takes a prompt template .md).
then we have --no-skills, --no-extensions --no-theme and --no-prompt-templates, and if we also specify --skill, --theme, --prompt-template, --extension, those get added back.
is that consistent?
Confirming parseArgs changes and ResourceLoader interface
I'll confirm the parseArgs updates are consistent and ask for final approval on the ResourceLoader interface. Then I'll provide the updated implementation plan.
Yes, consistent.
I will add:
Disable flags:
Behavior:
If this is final, I will proceed to implementation.
not yet, we now still need to figure out how package manager factors into all of this.
in settings, or via --extension, what if a user specifics npm: or git:? what should happen?
Proposing package source handling
Suggest storing source URLs with schemes in settings for the package manager to resolve to paths. For CLI -e with schemes like npm: or git:, propose ephemeral installs unless already present; install commands should modify settings to add sources. Clarify local versus global install behavior and whether -e triggers install prompts or loads existing packages.
We need to define how source specs are handled in two contexts: settings.json and CLI flags.
Proposed behavior
Open decisions A. Should CLI npm or git sources be auto installed into global locations, without touching settings.json.
B. Should CLI npm or git sources trigger a settings change, same as pi install.
I suggest A for flags, B for install command. That keeps flags ephemeral and install explicit.
Please confirm:
Also decide whether --skill, --prompt-template, --theme should accept npm or git or only filesystem paths. If we allow npm or git, the package must include pi field or follow auto discovery rules.
npm: and git: are only for extensions, which themselves then can contain extension entry points, skills, prompts, and themes
Confirming readiness for next steps
Understood.
Behavior update
This means --skill, --theme, --prompt-template only accept filesystem paths. Same for settings.json entries in skills, prompts, themes.
Anything else to finalize before implementation.
i think they should go into a /tmp folder just for that run?
the bigger question is: is package manager auto-invoked at any point? or is the user supposed to use the additional cli args to manually trigger pulling in an extension specified in settings.json?
Proposing package manager auto-invoke questions
I suggest confirming if the loader should automatically resolve and install missing packages based on user settings or remain manual. Should CLI runs leverage a temporary directory like /tmp for transient installs? Would the user prefer explicit prompts before any install or fully automatic handling?
Proposal
CLI npm or git
Auto invocation of PackageManager
Optional behavior
Confirm if auto install on startup is acceptable, or if you want a prompt or a flag to opt out.
well, installing via package manager may take a while, so whoever constructs the default loader may also want to show visual feedback in the tui ... so we need a kind of progress thing.
Proposing package manager events for progress hook
I'm suggesting implementing progress indication via package manager events or callbacks to efficiently track installation or update status without external tools.
We can add progress callbacks to PackageManager and ResourceLoader.
Proposal
type PackageProgress = { source: string; phase: "resolve" | "install" | "update" | "done"; message?: string };Interactive mode can pass a handler that updates a loader or status line.
If you want, I can add a lightweight interface like:
interface ResourceLoaderProgress { phase: "extensions" | "skills" | "prompts" | "themes" | "context" | "system" | "package"; message: string;}Confirm which shape you want.
what does package manager do concretely? where does it put the things?
Concrete PackageManager behavior proposal
Global install locations
npm root -g to find global node_modules. If source is npm:@scope/pkg@1.2.3, install via npm install -g @scope/pkg@1.2.3, then resolve path via node_modules/@scope/pkg.~/.pi/agent/git/<host>/<path>/<ref?> or similar. Use ~/.pi/agent/git/github.com/user/repo/ and checkout ref. If no ref, track default branch and update via fetch + reset.Local install locations
Temp installs for CLI flags
Actions
Pinning
If this matches, I will proceed.
what does package manager return to the loader then? would it itself be a resource loader?
Clarifying package manager role
The package manager returns resolved directory paths along with metadata but does not load resources itself; loaders consume these paths to fetch content. Progress reporting depends on the package manager implementation and usage context.
PackageManager is not a ResourceLoader. It is a dependency of DefaultResourceLoader.
PackageManager returns resolved paths for extension sources:
DefaultResourceLoader then applies extension discovery rules inside those directories, or uses pi field if present.
So the chain is: settings.json or CLI sources -> DefaultResourceLoader -> PackageManager.resolve -> resolved directories -> extension discovery -> ExtensionLoaderResult, skills, prompts, themes.
If you want PackageManager to expose a higher level helper like resolveExtensionSources to return arrays of paths, I can add that, but it still is not a ResourceLoader.
ok. what if the project local settings.json has npm in it? will that also be installed to the global npm modules?
Confirming global npm install decision
The npm modules will be installed globally following the npm root -g path, even if project local settings.json specifies npm. This behavior can be changed by adding a local install flag, but currently global install is the default. Should I proceed with this approach or adjust it?
With the current decision to use npm root -g, yes. Any npm: source in project settings would still install into the global npm modules directory.
If you want project settings to install into a project local cache instead, I can add a local mode. That would need a rule like: project settings use /.pi/npm/node_modules while global settings use npm root -g.
what did the original issue say about that?
Referencing issue content
The answer will note that the table distinguishes between global node_modules and local .pi/npm modules based on the issue summary.
Issue #645 specifies:
npm root -g.<cwd>/.pi/npm/node_modules/.So if we follow the issue, project settings would be local only when using the -l flag in install. Otherwise global.
ignore the -l flag and other shit we might add as an interface to the lci later. all that will do is modify the settings.json, either global or local. the rest will then be handled by the default "pipeline". no?
Confirming pipeline and install location
The pipeline will run as planned. Should global installation proceed even if local settings include npm? Current understanding is yes, global install is still needed unless otherwise specified.
Yes. The CLI install or other management commands only mutate settings.json, either global or local. After that, the default loader pipeline handles resolve and install on startup or reload. With npm root -g, both global and project settings will install into the global node_modules path unless we introduce a separate local install location later.
soo, can we install to ./pi/npm/node_modules easily? in case we find a npm: extension in the project local settings.json?
Confirming npm install approach
Suggest installing with npm using a prefix for local installs (npm --prefix /.pi/npm install) and npm root -g for global; ask which approach is preferred. Also mention branching on the settings origin to handle global defaults and consider handling CLI extension temp paths.
Yes. Use npm install --prefix <cwd>/.pi/npm <pkg> and resolve path from <cwd>/.pi/npm/node_modules/<pkg>. We can detect origin of the source. If it comes from project settings, use local install dir. If it comes from global settings, use npm root -g.
Confirm if you want this split behavior now.
confirmed.
so back to when package-manager is triggered. read @packages/coding-agent/src/main.ts where in this flow would we do that? in the defaultresourceloader? which i guess we construct on startup to get extension cli flags?
Confirming default loader use
The default loader handles detecting the package manager and initializing with settings, no-extensions flags, and CLI extension sources; it parses once, creates the loader, then calls reload to load extensions and flags with progress tracking. Confirm if this approach is acceptable.
Yes. The default ResourceLoader owns PackageManager and should be used in both passes.
Flow in main.ts:
This keeps the package manager inside the default loader and ensures it runs during the early extension flag discovery.
Confirm if you want step 5 to reuse the same loaded result or to reload after setting flags.
well, flags can't modify anything wrt to resources, can theyß
Acknowledging request
Ready for the next input; will indicate when to reload after responding.
Extension flags do not affect resource loading. We can load once in the first pass, then only apply flag values to the runtime before creating the session. No second reload needed unless you want to re-read settings.json after parsing non extension flags.
ok, and a user of DefaultResourceLoader would not have to cnstruct their own package manager, correct?
Confirming resource loader design
The plan is to have DefaultResourceLoader.create build the package manager internally while allowing injection for tests, with ResourceLoader exposed in the SDK.
Correct. DefaultResourceLoader should create and own its PackageManager internally. We can still accept an optional PackageManager for tests, but callers should not need to construct one.
alright. what about models.json? and keybindings.json? do we have more .json files that could live in ~/.pi/agent or /.pi? what do we have atm? i think resourceloader should handle all those things, no?
Identifying config source
I'm reading the main config file to locate the list of configuration paths or patterns, aiming to find relevant config file names or locations before listing or inspecting them.
Clarifying resource loading scope
The ResourceLoader should focus on runtime session-related resources like extensions, skills, prompts, themes, agents, and system prompts, excluding models, keybindings, and auth config since they're outside session-loaded resources. Keybindings likely live in the keybindings manager and can be read there if needed, so checking keybindings.json with a read tool in that context makes sense for safety.
Clarifying ResourceLoader scope and config files
ResourceLoader should only handle session-visible resources like extensions, skills, prompts, themes, context, and system prompts. Core config files such as models.json, auth.json, keybindings.json, and settings.json belong elsewhere and are not managed by ResourceLoader.
Defining ownership of core config files
Models.json, auth.json, and keybindings.json are managed respectively by ModelRegistry, AuthStorage, and KeybindingsManager; ResourceLoader should not handle them.
Current config and data files
Global (~/.pi/agent):
Project (/.pi):
Project context files outside .pi:
Recommendation ResourceLoader should only handle runtime resources that affect the session prompt and extension system:
It should not handle:
If you want ResourceLoader to handle settings.json too, that is a larger refactor. My suggestion is to keep settings in SettingsManager and let DefaultResourceLoader read from it.
no, that sounds good to me. alright, does it make sense to encode ALL our decisions above into a new comment on the issue 645 that describes everything in detail?
Confirming overview comment offer
I'll confirm that encoding all decisions into a detailed comment on issue 645 makes sense and offer to draft and post it, asking for approval before posting while noting no implementation will happen now.
Yes. A single comment on #645 that consolidates the final design and decisions will prevent drift. If you want, I can post it as a structured checklist covering ResourceLoader API, DefaultResourceLoader behavior, package manager rules, settings layout, CLI flags, and reload flow.
do that please. i suggest you first write to a local file, then upload that as a comment via gh cli
Drafting concise issue comment
I'm preparing a clear technical comment listing key decisions: ResourceLoader interface, diagnostic updates, default discovery changes, merged settings arrays with conflict checks, new CLI flags replacing --skills filter, npm root and local install behavior, temp use for CLI npm/git in extensions, and the two-pass reload flow. I'll avoid em dashes and ornate language for clarity before saving and posting the comment via GitHub CLI.
>gh issue comment 645 -F /Users/badlogic/workspaces/pi-mono/tmp/issue-645-comment.mdComment posted: https://github.com/badlogic/pi-mono/issues/645#issuecomment-3770700174
If you want any edits to the comment, say which parts to adjust.
could you implement this based on just that comment? i HIGHLY doubt that ... add all the detalis needed, so the comment is self-conatined, contains all shapes, all files you need to read and modify, etc.
Planning detailed comment update
I'm clarifying that updating the external comment requires reading and modifying local files first, then posting a new GitHub issue comment rather than editing the existing one. I'll include specifics like which files to change, interface definitions, and flow details in the new comment.
>gh issue comment 645 -F /Users/badlogic/workspaces/pi-mono/tmp/issue-645-comment-v2.mdPosted expanded comment: https://github.com/badlogic/pi-mono/issues/645#issuecomment-3770703260
If you want any adjustments, list them and I will update with a follow-up comment.
export interface ResourceLoader { getExtensions(): LoadExtensionsResult; getSkills(): { skills: Skill[]; warnings: SkillWarning[] }; getPrompts(): { prompts: PromptTemplate[]; warnings: PromptTemplateWarning[] }; getThemes(): { themes: Theme[]; warnings: ThemeWarning[] }; getAgentsFiles(): { agentsFiles: Array<{ path: string; content: string }> }; getSystemPrompt(): string | undefined; getAppendSystemPrompt(): string[]; // one or more fragments reload(): Promise<void>;}export interface ResourceDiagnostic { type: "warning" | "error"; message: string; path?: string;}getSkills(): { skills: Skill[]; diagnostics: ResourceDiagnostic[] }type PackageProgress = { source: string; phase: "resolve" | "install" | "update" | "done"; message?: string };interface ResourceLoaderProgress { phase: "extensions" | "skills" | "prompts" | "themes" | "context" | "system" | "package"; message: string;}