HOMELAB-1609: feat(extensions): vendor skill-args, todo, and ask-user-question from @juicesharp/* #37
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "plane/HOMELAB-1609-ext"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Extension-port leg of HOMELAB-1609 (uninstall
@juicesharp/rpiv-*pi packages after porting the used surface). Vendors the MIT-licensed source of three npm packages into this repo as first-class extensions:skill-args/@juicesharp/rpiv-args/skill:expansion engine (input+before_agent_starthooks)todo/@juicesharp/rpiv-todotodotool +/todoscommand + overlay widgetask-user-question/@juicesharp/rpiv-ask-user-questionask_user_questiontool (full UI + RPC fallback + external editor)De-rpiv'ing (no
@juicesharp/*imports remain)rpiv-config→ inlinedlocal-config.tsper package (loadJsonConfigWithLegacyFallback,validateGuidanceFields,GuidanceFields). XDG path resolution, legacy~/.config/<name>/config.jsonfallback, andvalidateGuidanceFieldssemantics are byte-identical. Config dir names stayrpiv-todo/rpiv-ask-user-questionon purpose, so existing user configs keep working.rpiv-i18n→ stripped. Bothstate/i18n-bridge.tsfiles are a constant English identity passthrough — exactly the behavior that already ran when the optional SDK was absent. Therpiv-i18n/loaderregistration block and the now-inertlocales/directories were removed.rpiv-pi/rpiv-coreimports existed in any of the three packages (verified by grep).todo/ask_user_questionand command nametodosare unchanged;skill-argspreserves the byte-exact<skill name=… location=…>wrapper, theSkill input:trailer,$N/$ARGUMENTSgating, always-on${SKILL_DIR}/${SESSION_ID}and shell substitution, block-output masking, and theshell-timeoutfrontmatter override (0 = disable).Verification (run in this worktree)
skill-args/tests/args-pipeline.test.tsis the migration safety net: 32 tests over the full expansion pipeline (substitution, shell execution order, block masking, timeout resolution, wrapper byte-format). Smoke tests in each package assert the default export registers the expected tool/command/handler names against a mockExtensionAPI.CI: three new
typecheck+npm testjobs in.forgejo/workflows/ci.yaml, mirroring the existing packages.Not in this PR
pi-skills/+pi-swarm-suite/agents/(owned by the parallel skills/agents worktree).npm uninstallof the@juicesharp/*packages, settings.json edits, and live boot verification (orchestrator, post-merge).Notes for the orchestrator
~/.pi/agent/settings.jsonstill lists the external@juicesharp/*packages, so the live boot will not pick these vendored copies up until the uninstall/settings step lands. Do not expect duplicate-tool protection from the vendored dirs alone.rpiv-pi'ssiblings.tsregistry does namerpiv-ask-user-question,rpiv-todo, andrpiv-args; once they are removed from settings, rpiv-pi reports them as missing plugins and/rpiv-setupwould try to reinstall them. If rpiv-pi is also being uninstalled this is moot; otherwise its sibling registry needs reconciling.MIT-licensed port of @juicesharp/rpiv-args with no @juicesharp/* runtime imports (the package had none). Preserves the full expansion pipeline byte-for-byte: $N/$ARGUMENTS gated by TOKEN_REGEX, ${SKILL_DIR}/${SESSION_ID} always-on, inline !`cmd` and fenced ! shell substitution with block-output masking, 120s default timeout with per-skill shell-timeout frontmatter override (0 = disable), the exact <skill name=... location=...> wrapper, the 'Skill input:' trailer, and the before_agent_start skill-invocation protocol. Adds package.json/tsconfig/vitest config mirroring pi-swarm-suite, plus 36 tests (smoke + full pipeline).CI green on
99e57f7:.forgejo/workflows/ci.yamlrun "HOMELAB-1609: ci(forgejo): gate the three vendored extension packages" → [success] (pr-title+skill-args+todo+ask-user-questionall passed; existingpi-swarm-suite/pi-otel-telemetryjobs untouched).Local reproduction in the worktree (paste from the leg report):
skill-args:tsc --noEmitexit 0 ·vitest run→ 36 passed (2 files)todo:tsc --noEmitexit 0 ·vitest run→ 4 passed (1 file)ask-user-question:tsc --noEmitexit 0 ·vitest run→ 4 passed (1 file)Independent review verdict — HOMELAB-1609 extension port (PR #37, head
99e57f7)Verdict: APPROVE — no blockers. CI green on the head commit; merging.
Two fresh-context reviewers ran independently (separate
pi -p --no-sessionprocesses, primary sources only: the diff, the checked-out branch, the upstream MIT packages at~/.pi/agent/npm/node_modules/@juicesharp/*). Both returned no blockers; the landing worker independently reproduced the load-bearing checks below. Reviewer ≠ implementer.Verified with commands (not claims)
GET /commits/99e57f7…/status→ state: success, 6/6 contexts (pr-title, pi-swarm-suite, pi-otel-telemetry, skill-args, todo, ask-user-question)npm ci && npx tsc --noEmit && npx vitest runper package → tsc exit 0 ×3; skill-args 36 passed (2 files), todo 4 passed, ask-user-question 4 passed — matches the PR body exactlydiff -rq ~/.pi/agent/npm/node_modules/@juicesharp/rpiv-{args,todo,ask-user-question} <vendored>→ onlyindex.ts,package.json,state/i18n-bridge.ts,config.tsdiffer (+ new tests/tsconfig/vitest.config/local-config.ts;locales/removed)skill-args/args.tsmd5sum→78544b68f06f78c0e26dfcb18c4e98bbon both sides — byte-identical, so the wrapper format,Skill input:trailer,$N/$ARGUMENTSgating, always-on${SKILL_DIR}/${SESSION_ID}, inline+fenced shell, block-output masking andshell-timeoutresolution are preserved by constructionconfig.tshunks@juicesharp/rpiv-config→./local-config.js); config dir names preserved ("rpiv-todo","rpiv-ask-user-question")local-config.tsresolveConfigDirinlinesprocess.env.XDG_CONFIG_HOME?.trim()≡ upstreamreadEnvVar(...);expandTilde/legacyConfigPath/loadJsonConfigWithLegacyFallback/validateGuidanceFieldslogic-identical; the un-vendored surface (saveJsonConfig,validateConfig,modelKey,parseModelKey) is referenced nowhere — reduced write surface@juicesharpimports/requires/dynamic-imports in all.ts; 0 occurrences in all three lockfiles; cleannpm cipulls no@juicesharppackage. The remaining occurrences are comments,package.jsondescriptions, or docs (the allowed MIT-attribution class)TOOL_NAME = "todo",COMMAND_NAME = "todos"(todo/tool/types.ts:11,13),ASK_USER_QUESTION_TOOL_NAME = "ask_user_question"(ask-user-question/ask-user-question.ts:74); widget key"rpiv-todos"preserved (todo/todo-overlay.ts:23)I18N_NAMESPACEconsumers and therpiv-i18n/loaderblock removed; nolocales/registerLocalesFromDirreferences remain;locales/dirs gonegit diff --name-status main...HEAD→ 94 added, 2 modified (.forgejo/workflows/ci.yaml,README.md), 0 deleted; nonode_modulescommittedlocal-configvs realrpiv-config@2.10.1over XDG/legacy/malformed/tilde/relative edge cases → 6/6 identical; 12-caseloadJsonConfigcorpus and 30-case hostilevalidateGuidanceFieldscorpus → identical; everyt(key, fallback)cross-checked against the shippeden.json→ 0 mismatchesConcerns (non-blocking, for follow-up)
{todo,ask-user-question}/config.ts+state/i18n-bridge.ts) have zero tests, while 32 tests protectskill-args/args.ts— a file that was not modified and has no@juicesharpdependency upstream. Both reviewers closed the gap externally (differential harness above), but the repo's own evidence for two acceptance criteria is currently a comment. A ~10-case matrix with a tempHOME/XDG_CONFIG_HOMEwould pin it after the upstream reference is gone.todo/local-config.ts:107/ask-user-question/local-config.ts:107warnlocal-config: invalid JSON at …where upstream emittedrpiv-config: …. Behaviorally inert; log greps change. Related doc drift:todo/docs/configuration.md:23andask-user-question/docs/configuration.md:50still quote the oldrpiv-config:string.todo/README.md:65,115,todo/docs/overlay.md:118,126,128,ask-user-question/README.md:89,ask-user-question/docs/localization.md— all promise nine bundled locales andpi install npm:@juicesharp/rpiv-i18nchrome. No locales ship and no registration path exists any more. A three-line "Vendored — the install instructions below refer to upstream" header per README would resolve it.ask-user-question/docs/tool-schema.md:113still showsfrom "@juicesharp/rpiv-ask-user-question/events"for an event contract that now lives in./events.ts.@juicesharp/rpiv-todo/-argsas "installed separately … not part of this repo" while lines 37-44 add them as repo members.2.10.1). The repo precedent pins it:NOTICE:6-7records@tintinweb/pi-subagents v0.10.3forpi-swarm-suite. Since byte-exactness is the acceptance criterion, the source release should be recorded before the npm packages are uninstalled. (MIT attribution itself is satisfied: per-dirLICENSEfiles are the genuine upstream MIT text withCopyright (c) 2026 juicesharp, plusdescription/header attribution.)NOTICEnot updated to list the three new vendored packages, unlike the existingpi-swarm-suiteentry.@juicesharp/rpiv-i18nwas installed and the loader was registering locales. The defensible justification is what was verified: no~/.config/rpiv-i18n/locale.jsonexists, the active locale isundefined, anden.jsonis byte-identical to every inline fallback → zero visible change today. Residual loss:/languagesfor these two namespaces.skill-args/todo/ask-user-questionas required checks or a red run still merges. Not verifiable from the repo (read-only review).~/.pi/agent/extensionsis a separate clone of this repo, so pulling it loads these three dirs whilesettings.jsonstill lists the npm packages →todo/ask_user_questionregister twice until the npm uninstall + settings step lands.skill-argsis already safe there (args.tsWRAPPED_PREFIXre-entrancy guard). pi's exact behavior on two same-name tools is unverified; the orchestrator step must remove the npm entries and settings lines atomically.skill-args'ssession_startindex invalidation onreason: "reload"|"startup"is asserted only for handler count (smoke.test.ts:30); the/reloadre-enumeration path is unasserted.Deferred acceptance legs (named, not silently skipped)
settings.json, which this landing must not do.locale.json), so i18n equivalence is verified for the current configuration, not in general (accepted by the frozen criterion).Landed.
Merged as
cf064e3186f4ac8b0990a24b716ede7a7970b0fb(merge commit, source branch kept).Landing notes
mainadvanced to901fe7a(PR #36, skills+agents leg) after CI went green on99e57f7, and that leg added api-skillsrow to the README extension table at the same position as this PR's three rows.mergeablewentfalsewith a real content conflict inREADME.md, so a conflict-resolution commit was added:72e625a— "HOMELAB-1609: merge main into plane/HOMELAB-1609-ext", resolving README by keeping thepi-skillsrow first, thenskill-args/todo/ask-user-question+ the vendored note. Nothing else was resolved or edited.git diff --stat 99e57f7 HEAD -- skill-args todo ask-user-question→ empty. The three reviewed directories are tree-identical to the SHA the independent reviewers read; onlyREADME.mdchanged.72e625a— 6/6 contexts success (pr-title,pi-swarm-suite,pi-otel-telemetry,skill-args,todo,ask-user-question). Merged only after that.~/.pi/agent/extensions, a separate clone of this repo): fast-forward901fe7a→cf064e3, tree identical toorigin/main,skill-args/+todo/+ask-user-question/now present.skill-args/args.tsmd578544b68f06f78c0e26dfcb18c4e98bb— unchanged from the npm package.settings.jsonedit, nonpm uninstall,~/.pi/agent/agents/.rpiv-managed.jsonuntouched. ⚠️ This means the duplicate-registration window is now open (concern 10): the three dirs load from the live clone whilesettings.jsonstill listsnpm:@juicesharp/rpiv-{args,todo,ask-user-question}, sotodo/ask_user_questionwill double-register on the next pi boot until the uninstall + settings edit land atomically.skill-argsis safe (args.tsre-entrancy guard).Concerns 1–11 from the review verdict above remain open and unaddressed by this landing; concerns 1 (no tests for
local-config.ts/i18n-bridge.ts), 6 (upstream version2.10.1not pinned in-repo — note PR #36's leg did add aNOTICEline forpi-skills, so this leg is now visibly the outlier) and 3 (docs describing removed i18n capability) are the ones worth a follow-up ticket.