harnery 0.0.1 → 0.2.1
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/LICENSE +21 -0
- package/README.md +84 -2
- package/bin/agent-coord +42 -0
- package/bin/agent-hook +44 -0
- package/bin/harn +40 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +18 -0
- package/dist/commander.d.ts +128 -0
- package/dist/commander.d.ts.map +1 -0
- package/dist/commander.js +126 -0
- package/dist/commands/agents.d.ts +18 -0
- package/dist/commands/agents.d.ts.map +1 -0
- package/dist/commands/agents.js +3946 -0
- package/dist/commands/backup.d.ts +22 -0
- package/dist/commands/backup.d.ts.map +1 -0
- package/dist/commands/backup.js +262 -0
- package/dist/commands/browse-ai.d.ts +4 -0
- package/dist/commands/browse-ai.d.ts.map +1 -0
- package/dist/commands/browse-ai.js +156 -0
- package/dist/commands/browse.d.ts +4 -0
- package/dist/commands/browse.d.ts.map +1 -0
- package/dist/commands/browse.js +590 -0
- package/dist/commands/callers.d.ts +4 -0
- package/dist/commands/callers.d.ts.map +1 -0
- package/dist/commands/callers.js +276 -0
- package/dist/commands/completion.d.ts +17 -0
- package/dist/commands/completion.d.ts.map +1 -0
- package/dist/commands/completion.js +158 -0
- package/dist/commands/config-get.d.ts +4 -0
- package/dist/commands/config-get.d.ts.map +1 -0
- package/dist/commands/config-get.js +131 -0
- package/dist/commands/context.d.ts +11 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +185 -0
- package/dist/commands/cookies.d.ts +4 -0
- package/dist/commands/cookies.d.ts.map +1 -0
- package/dist/commands/cookies.js +140 -0
- package/dist/commands/docs.d.ts +4 -0
- package/dist/commands/docs.d.ts.map +1 -0
- package/dist/commands/docs.js +137 -0
- package/dist/commands/doctor.d.ts +25 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +200 -0
- package/dist/commands/edit-batch.d.ts +18 -0
- package/dist/commands/edit-batch.d.ts.map +1 -0
- package/dist/commands/edit-batch.js +172 -0
- package/dist/commands/eml.d.ts +4 -0
- package/dist/commands/eml.d.ts.map +1 -0
- package/dist/commands/eml.js +428 -0
- package/dist/commands/env.d.ts +4 -0
- package/dist/commands/env.d.ts.map +1 -0
- package/dist/commands/env.js +201 -0
- package/dist/commands/fetch.d.ts +4 -0
- package/dist/commands/fetch.d.ts.map +1 -0
- package/dist/commands/fetch.js +99 -0
- package/dist/commands/file-history.d.ts +4 -0
- package/dist/commands/file-history.d.ts.map +1 -0
- package/dist/commands/file-history.js +152 -0
- package/dist/commands/grep.d.ts +4 -0
- package/dist/commands/grep.d.ts.map +1 -0
- package/dist/commands/grep.js +317 -0
- package/dist/commands/init.d.ts +82 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +288 -0
- package/dist/commands/outline.d.ts +4 -0
- package/dist/commands/outline.d.ts.map +1 -0
- package/dist/commands/outline.js +509 -0
- package/dist/commands/presence.d.ts +12 -0
- package/dist/commands/presence.d.ts.map +1 -0
- package/dist/commands/presence.js +123 -0
- package/dist/commands/read.d.ts +7 -0
- package/dist/commands/read.d.ts.map +1 -0
- package/dist/commands/read.js +46 -0
- package/dist/commands/scratch.d.ts +4 -0
- package/dist/commands/scratch.d.ts.map +1 -0
- package/dist/commands/scratch.js +426 -0
- package/dist/commands/session.d.ts +4 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +162 -0
- package/dist/commands/sync.d.ts +24 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +275 -0
- package/dist/commands/toc.d.ts +5 -0
- package/dist/commands/toc.d.ts.map +1 -0
- package/dist/commands/toc.js +153 -0
- package/dist/commands/tokens.d.ts +4 -0
- package/dist/commands/tokens.d.ts.map +1 -0
- package/dist/commands/tokens.js +48 -0
- package/dist/commands/tunnel.d.ts +4 -0
- package/dist/commands/tunnel.d.ts.map +1 -0
- package/dist/commands/tunnel.js +513 -0
- package/dist/commands/uninstall.d.ts +22 -0
- package/dist/commands/uninstall.d.ts.map +1 -0
- package/dist/commands/uninstall.js +126 -0
- package/dist/commands/web.d.ts +4 -0
- package/dist/commands/web.d.ts.map +1 -0
- package/dist/commands/web.js +165 -0
- package/dist/core/agents/canonical-emit.d.ts +27 -0
- package/dist/core/agents/canonical-emit.d.ts.map +1 -0
- package/dist/core/agents/canonical-emit.js +72 -0
- package/dist/core/agents/cli-emit.d.ts +27 -0
- package/dist/core/agents/cli-emit.d.ts.map +1 -0
- package/dist/core/agents/cli-emit.js +57 -0
- package/dist/core/agents/cli.d.ts +10 -0
- package/dist/core/agents/cli.d.ts.map +1 -0
- package/dist/core/agents/cli.js +757 -0
- package/dist/core/agents/codex-replay.d.ts +29 -0
- package/dist/core/agents/codex-replay.d.ts.map +1 -0
- package/dist/core/agents/codex-replay.js +138 -0
- package/dist/core/agents/coord-client.d.ts +98 -0
- package/dist/core/agents/coord-client.d.ts.map +1 -0
- package/dist/core/agents/coord-client.js +212 -0
- package/dist/core/agents/events/consume.d.ts +59 -0
- package/dist/core/agents/events/consume.d.ts.map +1 -0
- package/dist/core/agents/events/consume.js +147 -0
- package/dist/core/agents/events/emit.d.ts +42 -0
- package/dist/core/agents/events/emit.d.ts.map +1 -0
- package/dist/core/agents/events/emit.js +70 -0
- package/dist/core/agents/events/ulid.d.ts +11 -0
- package/dist/core/agents/events/ulid.d.ts.map +1 -0
- package/dist/core/agents/events/ulid.js +47 -0
- package/dist/core/agents/index.d.ts +14 -0
- package/dist/core/agents/index.d.ts.map +1 -0
- package/dist/core/agents/index.js +13 -0
- package/dist/core/agents/paths.d.ts +6 -0
- package/dist/core/agents/paths.d.ts.map +1 -0
- package/dist/core/agents/paths.js +17 -0
- package/dist/core/agents/render/prompt-context.d.ts +43 -0
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -0
- package/dist/core/agents/render/prompt-context.js +335 -0
- package/dist/core/agents/render/session-context.d.ts +39 -0
- package/dist/core/agents/render/session-context.d.ts.map +1 -0
- package/dist/core/agents/render/session-context.js +283 -0
- package/dist/core/agents/rules/claim-conflict.d.ts +35 -0
- package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -0
- package/dist/core/agents/rules/claim-conflict.js +244 -0
- package/dist/core/agents/rules/commit-conflict.d.ts +59 -0
- package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -0
- package/dist/core/agents/rules/commit-conflict.js +244 -0
- package/dist/core/agents/rules/stop-hook.d.ts +44 -0
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -0
- package/dist/core/agents/rules/stop-hook.js +161 -0
- package/dist/core/agents/session-events.d.ts +41 -0
- package/dist/core/agents/session-events.d.ts.map +1 -0
- package/dist/core/agents/session-events.js +205 -0
- package/dist/core/agents/state/activity-log.d.ts +18 -0
- package/dist/core/agents/state/activity-log.d.ts.map +1 -0
- package/dist/core/agents/state/activity-log.js +34 -0
- package/dist/core/agents/state/council.d.ts +39 -0
- package/dist/core/agents/state/council.d.ts.map +1 -0
- package/dist/core/agents/state/council.js +216 -0
- package/dist/core/agents/state/heartbeat-projector.d.ts +59 -0
- package/dist/core/agents/state/heartbeat-projector.d.ts.map +1 -0
- package/dist/core/agents/state/heartbeat-projector.js +436 -0
- package/dist/core/agents/state/heartbeat-writer.d.ts +64 -0
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -0
- package/dist/core/agents/state/heartbeat-writer.js +271 -0
- package/dist/core/agents/state/names.d.ts +35 -0
- package/dist/core/agents/state/names.d.ts.map +1 -0
- package/dist/core/agents/state/names.js +376 -0
- package/dist/core/agents/state/pidmap.d.ts +11 -0
- package/dist/core/agents/state/pidmap.d.ts.map +1 -0
- package/dist/core/agents/state/pidmap.js +32 -0
- package/dist/core/agents/state/scratch.d.ts +27 -0
- package/dist/core/agents/state/scratch.d.ts.map +1 -0
- package/dist/core/agents/state/scratch.js +90 -0
- package/dist/core/agents/state/shell-mutation.d.ts +17 -0
- package/dist/core/agents/state/shell-mutation.d.ts.map +1 -0
- package/dist/core/agents/state/shell-mutation.js +41 -0
- package/dist/core/agents/state/stale-sweep.d.ts +16 -0
- package/dist/core/agents/state/stale-sweep.d.ts.map +1 -0
- package/dist/core/agents/state/stale-sweep.js +166 -0
- package/dist/core/config.d.ts +29 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +108 -0
- package/dist/core/hooks/cli.d.ts +21 -0
- package/dist/core/hooks/cli.d.ts.map +1 -0
- package/dist/core/hooks/cli.js +1123 -0
- package/dist/core/hooks/effects/image-capture.d.ts +43 -0
- package/dist/core/hooks/effects/image-capture.d.ts.map +1 -0
- package/dist/core/hooks/effects/image-capture.js +288 -0
- package/dist/core/hooks/effects/index.d.ts +64 -0
- package/dist/core/hooks/effects/index.d.ts.map +1 -0
- package/dist/core/hooks/effects/index.js +197 -0
- package/dist/core/hooks/events/emit.d.ts +31 -0
- package/dist/core/hooks/events/emit.d.ts.map +1 -0
- package/dist/core/hooks/events/emit.js +89 -0
- package/dist/core/hooks/events/schema.d.ts +235 -0
- package/dist/core/hooks/events/schema.d.ts.map +1 -0
- package/dist/core/hooks/events/schema.js +12 -0
- package/dist/core/hooks/events/ulid.d.ts +10 -0
- package/dist/core/hooks/events/ulid.d.ts.map +1 -0
- package/dist/core/hooks/events/ulid.js +47 -0
- package/dist/core/hooks/harness/detect.d.ts +9 -0
- package/dist/core/hooks/harness/detect.d.ts.map +1 -0
- package/dist/core/hooks/harness/detect.js +29 -0
- package/dist/core/hooks/harness/events.d.ts +45 -0
- package/dist/core/hooks/harness/events.d.ts.map +1 -0
- package/dist/core/hooks/harness/events.js +71 -0
- package/dist/core/hooks/harness/output.d.ts +46 -0
- package/dist/core/hooks/harness/output.d.ts.map +1 -0
- package/dist/core/hooks/harness/output.js +87 -0
- package/dist/core/hooks/harness/parse.d.ts +67 -0
- package/dist/core/hooks/harness/parse.d.ts.map +1 -0
- package/dist/core/hooks/harness/parse.js +132 -0
- package/dist/core/hooks/index.d.ts +8 -0
- package/dist/core/hooks/index.d.ts.map +1 -0
- package/dist/core/hooks/index.js +7 -0
- package/dist/core/hooks/resolve/anchor.d.ts +37 -0
- package/dist/core/hooks/resolve/anchor.d.ts.map +1 -0
- package/dist/core/hooks/resolve/anchor.js +48 -0
- package/dist/core/hooks/resolve/coord-root.d.ts +6 -0
- package/dist/core/hooks/resolve/coord-root.d.ts.map +1 -0
- package/dist/core/hooks/resolve/coord-root.js +27 -0
- package/dist/core/hooks/resolve/intent.d.ts +33 -0
- package/dist/core/hooks/resolve/intent.d.ts.map +1 -0
- package/dist/core/hooks/resolve/intent.js +79 -0
- package/dist/core/hooks/resolve/owner.d.ts +42 -0
- package/dist/core/hooks/resolve/owner.d.ts.map +1 -0
- package/dist/core/hooks/resolve/owner.js +140 -0
- package/dist/core/hooks/resolve/transcript.d.ts +26 -0
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -0
- package/dist/core/hooks/resolve/transcript.js +73 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/lib/agent-browser/client.d.ts +99 -0
- package/dist/lib/agent-browser/client.d.ts.map +1 -0
- package/dist/lib/agent-browser/client.js +177 -0
- package/dist/lib/agent-browser/index.d.ts +2 -0
- package/dist/lib/agent-browser/index.d.ts.map +1 -0
- package/dist/lib/agent-browser/index.js +1 -0
- package/dist/lib/browser/client.d.ts +193 -0
- package/dist/lib/browser/client.d.ts.map +1 -0
- package/dist/lib/browser/client.js +325 -0
- package/dist/lib/browser/dev-overlay.d.ts +23 -0
- package/dist/lib/browser/dev-overlay.d.ts.map +1 -0
- package/dist/lib/browser/dev-overlay.js +153 -0
- package/dist/lib/browser/index.d.ts +5 -0
- package/dist/lib/browser/index.d.ts.map +1 -0
- package/dist/lib/browser/index.js +2 -0
- package/dist/lib/browser/layout.d.ts +79 -0
- package/dist/lib/browser/layout.d.ts.map +1 -0
- package/dist/lib/browser/layout.js +220 -0
- package/dist/lib/browser/visibility.d.ts +86 -0
- package/dist/lib/browser/visibility.d.ts.map +1 -0
- package/dist/lib/browser/visibility.js +333 -0
- package/dist/lib/browser/visual-diff.d.ts +38 -0
- package/dist/lib/browser/visual-diff.d.ts.map +1 -0
- package/dist/lib/browser/visual-diff.js +107 -0
- package/dist/lib/completion/bash.d.ts +25 -0
- package/dist/lib/completion/bash.d.ts.map +1 -0
- package/dist/lib/completion/bash.js +284 -0
- package/dist/lib/completion/fish.d.ts +16 -0
- package/dist/lib/completion/fish.d.ts.map +1 -0
- package/dist/lib/completion/fish.js +118 -0
- package/dist/lib/completion/index.d.ts +5 -0
- package/dist/lib/completion/index.d.ts.map +1 -0
- package/dist/lib/completion/index.js +4 -0
- package/dist/lib/completion/walk.d.ts +68 -0
- package/dist/lib/completion/walk.d.ts.map +1 -0
- package/dist/lib/completion/walk.js +102 -0
- package/dist/lib/completion/zsh.d.ts +13 -0
- package/dist/lib/completion/zsh.d.ts.map +1 -0
- package/dist/lib/completion/zsh.js +249 -0
- package/dist/lib/context/index.d.ts +107 -0
- package/dist/lib/context/index.d.ts.map +1 -0
- package/dist/lib/context/index.js +275 -0
- package/dist/lib/cookies/client.d.ts +131 -0
- package/dist/lib/cookies/client.d.ts.map +1 -0
- package/dist/lib/cookies/client.js +239 -0
- package/dist/lib/cookies/index.d.ts +2 -0
- package/dist/lib/cookies/index.d.ts.map +1 -0
- package/dist/lib/cookies/index.js +1 -0
- package/dist/lib/council/index.d.ts +266 -0
- package/dist/lib/council/index.d.ts.map +1 -0
- package/dist/lib/council/index.js +674 -0
- package/dist/lib/docs-index.d.ts +28 -0
- package/dist/lib/docs-index.d.ts.map +1 -0
- package/dist/lib/docs-index.js +169 -0
- package/dist/lib/docs-lint.d.ts +26 -0
- package/dist/lib/docs-lint.d.ts.map +1 -0
- package/dist/lib/docs-lint.js +378 -0
- package/dist/lib/docs-sweep.d.ts +34 -0
- package/dist/lib/docs-sweep.d.ts.map +1 -0
- package/dist/lib/docs-sweep.js +304 -0
- package/dist/lib/docs.d.ts +27 -0
- package/dist/lib/docs.d.ts.map +1 -0
- package/dist/lib/docs.js +142 -0
- package/dist/lib/env.d.ts +11 -0
- package/dist/lib/env.d.ts.map +1 -0
- package/dist/lib/env.js +12 -0
- package/dist/lib/exec.d.ts +32 -0
- package/dist/lib/exec.d.ts.map +1 -0
- package/dist/lib/exec.js +54 -0
- package/dist/lib/format.d.ts +29 -0
- package/dist/lib/format.d.ts.map +1 -0
- package/dist/lib/format.js +139 -0
- package/dist/lib/http/client.d.ts +56 -0
- package/dist/lib/http/client.d.ts.map +1 -0
- package/dist/lib/http/client.js +160 -0
- package/dist/lib/http/index.d.ts +2 -0
- package/dist/lib/http/index.d.ts.map +1 -0
- package/dist/lib/http/index.js +1 -0
- package/dist/lib/identities/index.d.ts +77 -0
- package/dist/lib/identities/index.d.ts.map +1 -0
- package/dist/lib/identities/index.js +190 -0
- package/dist/lib/machine.d.ts +19 -0
- package/dist/lib/machine.d.ts.map +1 -0
- package/dist/lib/machine.js +61 -0
- package/dist/lib/presence.d.ts +48 -0
- package/dist/lib/presence.d.ts.map +1 -0
- package/dist/lib/presence.js +123 -0
- package/dist/lib/readability/client.d.ts +39 -0
- package/dist/lib/readability/client.d.ts.map +1 -0
- package/dist/lib/readability/client.js +121 -0
- package/dist/lib/readability/index.d.ts +2 -0
- package/dist/lib/readability/index.d.ts.map +1 -0
- package/dist/lib/readability/index.js +1 -0
- package/dist/lib/scratch/index.d.ts +74 -0
- package/dist/lib/scratch/index.d.ts.map +1 -0
- package/dist/lib/scratch/index.js +393 -0
- package/dist/lib/tunnel/gate.d.ts +12 -0
- package/dist/lib/tunnel/gate.d.ts.map +1 -0
- package/dist/lib/tunnel/gate.js +101 -0
- package/dist/lib/tunnel/state.d.ts +34 -0
- package/dist/lib/tunnel/state.d.ts.map +1 -0
- package/dist/lib/tunnel/state.js +132 -0
- package/package.json +160 -8
- package/schemas/.gitkeep +0 -0
- package/schemas/config.schema.json +109 -0
- package/src/cli.ts +22 -0
- package/src/commander.ts +242 -0
- package/src/commands/.gitkeep +0 -0
- package/src/commands/agents.ts +4567 -0
- package/src/commands/backup.ts +305 -0
- package/src/commands/browse-ai.ts +198 -0
- package/src/commands/browse.ts +849 -0
- package/src/commands/callers.ts +363 -0
- package/src/commands/completion.ts +193 -0
- package/src/commands/config-get.ts +161 -0
- package/src/commands/context.ts +209 -0
- package/src/commands/cookies.ts +198 -0
- package/src/commands/docs.ts +174 -0
- package/src/commands/doctor.ts +231 -0
- package/src/commands/edit-batch.ts +233 -0
- package/src/commands/eml.ts +519 -0
- package/src/commands/env.ts +254 -0
- package/src/commands/fetch.ts +136 -0
- package/src/commands/file-history.ts +202 -0
- package/src/commands/grep.ts +371 -0
- package/src/commands/init.ts +335 -0
- package/src/commands/outline.ts +583 -0
- package/src/commands/presence.ts +152 -0
- package/src/commands/read.ts +64 -0
- package/src/commands/scratch.ts +445 -0
- package/src/commands/session.ts +187 -0
- package/src/commands/sync.ts +306 -0
- package/src/commands/toc.ts +218 -0
- package/src/commands/tokens.ts +79 -0
- package/src/commands/tunnel.ts +633 -0
- package/src/commands/uninstall.ts +144 -0
- package/src/commands/web.ts +193 -0
- package/src/core/agents/canonical-emit.ts +77 -0
- package/src/core/agents/cli-emit.ts +64 -0
- package/src/core/agents/cli.ts +838 -0
- package/src/core/agents/codex-replay.ts +163 -0
- package/src/core/agents/coord-client.ts +249 -0
- package/src/core/agents/events/consume.ts +196 -0
- package/src/core/agents/events/emit.ts +108 -0
- package/src/core/agents/events/ulid.ts +51 -0
- package/src/core/agents/index.ts +14 -0
- package/src/core/agents/paths.ts +16 -0
- package/src/core/agents/render/prompt-context.ts +401 -0
- package/src/core/agents/render/session-context.ts +341 -0
- package/src/core/agents/rules/claim-conflict.ts +282 -0
- package/src/core/agents/rules/commit-conflict.ts +303 -0
- package/src/core/agents/rules/stop-hook.ts +229 -0
- package/src/core/agents/session-events.ts +228 -0
- package/src/core/agents/state/activity-log.ts +33 -0
- package/src/core/agents/state/council.ts +265 -0
- package/src/core/agents/state/heartbeat-projector.ts +488 -0
- package/src/core/agents/state/heartbeat-writer.ts +333 -0
- package/src/core/agents/state/names.ts +399 -0
- package/src/core/agents/state/pidmap.ts +38 -0
- package/src/core/agents/state/scratch.ts +121 -0
- package/src/core/agents/state/shell-mutation.ts +44 -0
- package/src/core/agents/state/stale-sweep.ts +190 -0
- package/src/core/config.ts +111 -0
- package/src/core/hooks/cli.ts +1247 -0
- package/src/core/hooks/effects/image-capture.ts +330 -0
- package/src/core/hooks/effects/index.ts +210 -0
- package/src/core/hooks/events/emit.ts +120 -0
- package/src/core/hooks/events/schema.ts +430 -0
- package/src/core/hooks/events/ulid.ts +51 -0
- package/src/core/hooks/harness/detect.ts +30 -0
- package/src/core/hooks/harness/events.ts +102 -0
- package/src/core/hooks/harness/output.ts +100 -0
- package/src/core/hooks/harness/parse.ts +180 -0
- package/src/core/hooks/index.ts +16 -0
- package/src/core/hooks/resolve/anchor.ts +51 -0
- package/src/core/hooks/resolve/coord-root.ts +25 -0
- package/src/core/hooks/resolve/intent.ts +89 -0
- package/src/core/hooks/resolve/owner.ts +140 -0
- package/src/core/hooks/resolve/transcript.ts +72 -0
- package/src/hooks/.gitkeep +0 -0
- package/src/index.ts +15 -0
- package/src/lib/agent-browser/client.ts +239 -0
- package/src/lib/agent-browser/index.ts +1 -0
- package/src/lib/browser/client.ts +449 -0
- package/src/lib/browser/dev-overlay.ts +207 -0
- package/src/lib/browser/index.ts +24 -0
- package/src/lib/browser/layout.ts +288 -0
- package/src/lib/browser/visibility.ts +419 -0
- package/src/lib/browser/visual-diff.ts +150 -0
- package/src/lib/completion/bash.ts +291 -0
- package/src/lib/completion/fish.ts +134 -0
- package/src/lib/completion/index.ts +10 -0
- package/src/lib/completion/walk.ts +184 -0
- package/src/lib/completion/zsh.ts +262 -0
- package/src/lib/context/index.ts +386 -0
- package/src/lib/cookies/client.ts +301 -0
- package/src/lib/cookies/index.ts +13 -0
- package/src/lib/council/index.ts +803 -0
- package/src/lib/docs-index.ts +216 -0
- package/src/lib/docs-lint.ts +413 -0
- package/src/lib/docs-sweep.ts +348 -0
- package/src/lib/docs.ts +199 -0
- package/src/lib/env.ts +12 -0
- package/src/lib/exec.ts +74 -0
- package/src/lib/format.ts +147 -0
- package/src/lib/http/client.ts +211 -0
- package/src/lib/http/index.ts +1 -0
- package/src/lib/identities/index.ts +210 -0
- package/src/lib/machine.ts +61 -0
- package/src/lib/presence.ts +154 -0
- package/src/lib/readability/client.ts +169 -0
- package/src/lib/readability/index.ts +5 -0
- package/src/lib/readability/turndown-plugin-gfm.d.ts +10 -0
- package/src/lib/scratch/index.ts +470 -0
- package/src/lib/tunnel/gate.ts +113 -0
- package/src/lib/tunnel/state.ts +167 -0
- package/src/web/.gitkeep +0 -0
- package/index.js +0 -1
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
const DEFAULT_EXCLUDE_DIRS = [
|
|
3
|
+
".git",
|
|
4
|
+
".cache",
|
|
5
|
+
"node_modules",
|
|
6
|
+
"dist",
|
|
7
|
+
"build",
|
|
8
|
+
"out",
|
|
9
|
+
".next",
|
|
10
|
+
"vendor",
|
|
11
|
+
"__pycache__",
|
|
12
|
+
".venv",
|
|
13
|
+
"tmp",
|
|
14
|
+
"tmp-files",
|
|
15
|
+
"coverage",
|
|
16
|
+
".parcel-cache",
|
|
17
|
+
".turbo",
|
|
18
|
+
".harnery",
|
|
19
|
+
];
|
|
20
|
+
// (no file-name excludes by default).
|
|
21
|
+
const DEFAULT_EXCLUDE_FILES = [];
|
|
22
|
+
const LANG_GLOBS = {
|
|
23
|
+
ts: ["*.ts", "*.tsx"],
|
|
24
|
+
js: ["*.js", "*.jsx", "*.mjs", "*.cjs"],
|
|
25
|
+
py: ["*.py"],
|
|
26
|
+
php: ["*.php"],
|
|
27
|
+
rb: ["*.rb"],
|
|
28
|
+
go: ["*.go"],
|
|
29
|
+
rs: ["*.rs"],
|
|
30
|
+
};
|
|
31
|
+
export function registerCallersCommand(program, emit, context) {
|
|
32
|
+
program
|
|
33
|
+
.command("callers <symbol>")
|
|
34
|
+
.description("Find references to a symbol across the monorepo with kind classification " +
|
|
35
|
+
"(call / import / type / decl / ref). Heuristic: filters out declarations + " +
|
|
36
|
+
"single-line comments by default; opt back in with --include-decl / --include-comments.")
|
|
37
|
+
.option("--repo <name>", "Scope to one submodule (`.` = parent repo root)")
|
|
38
|
+
.option("--all-repos", "Search parent + every submodule")
|
|
39
|
+
.option("--lang <lang>", `File type preset (${Object.keys(LANG_GLOBS).join(", ")})`)
|
|
40
|
+
.option("--include-decl", "Include the declaration line(s) too")
|
|
41
|
+
.option("--include-comments", "Include matches in single-line comments")
|
|
42
|
+
.option("--limit <n>", "Truncate output to N matches total", "500")
|
|
43
|
+
.option("--json", "Structured JSON envelope")
|
|
44
|
+
.action(async (symbol, opts) => {
|
|
45
|
+
try {
|
|
46
|
+
const result = await runCallers(symbol, opts, context);
|
|
47
|
+
if (opts.json) {
|
|
48
|
+
emit.config({ format: "json" });
|
|
49
|
+
emit.data(result);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
emit.text(`${renderCallers(result)}\n`);
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
emit.error({ code: "callers_failed", message: err.message });
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
async function runCallers(symbol, opts, context) {
|
|
61
|
+
if (!/^[A-Za-z_$][\w$]*$/.test(symbol)) {
|
|
62
|
+
throw new Error(`symbol must be a valid identifier (got: ${symbol})`);
|
|
63
|
+
}
|
|
64
|
+
const started = Date.now();
|
|
65
|
+
const repos = resolveRepos(opts, context);
|
|
66
|
+
const limit = opts.limit ? Number.parseInt(opts.limit, 10) : 500;
|
|
67
|
+
const allCallers = [];
|
|
68
|
+
let truncated = false;
|
|
69
|
+
for (const repo of repos) {
|
|
70
|
+
if (allCallers.length >= limit) {
|
|
71
|
+
truncated = true;
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
const remaining = limit - allCallers.length;
|
|
75
|
+
const found = await grepInRepo(symbol, opts, repo, remaining);
|
|
76
|
+
if (found.truncated)
|
|
77
|
+
truncated = true;
|
|
78
|
+
allCallers.push(...found.callers);
|
|
79
|
+
}
|
|
80
|
+
const by_kind = {};
|
|
81
|
+
for (const c of allCallers) {
|
|
82
|
+
by_kind[c.kind] = (by_kind[c.kind] || 0) + 1;
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
symbol,
|
|
86
|
+
repos: repos.map((r) => ({ name: r.name, cwd: r.cwd })),
|
|
87
|
+
callers: allCallers,
|
|
88
|
+
by_kind,
|
|
89
|
+
total: allCallers.length,
|
|
90
|
+
truncated,
|
|
91
|
+
elapsed_ms: Date.now() - started,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function resolveRepos(opts, context) {
|
|
95
|
+
const repoRoot = context?.repoRoot;
|
|
96
|
+
const submodules = context?.submodules;
|
|
97
|
+
if (opts.allRepos) {
|
|
98
|
+
if (!repoRoot || !submodules) {
|
|
99
|
+
throw new Error("--all-repos requires harnery to be configured with repoRoot + submodules");
|
|
100
|
+
}
|
|
101
|
+
const out = [{ name: "parent", cwd: repoRoot }];
|
|
102
|
+
for (const name of submodules)
|
|
103
|
+
out.push({ name, cwd: `${repoRoot}/${name}` });
|
|
104
|
+
return out;
|
|
105
|
+
}
|
|
106
|
+
if (opts.repo) {
|
|
107
|
+
if (opts.repo === "." || opts.repo === "parent") {
|
|
108
|
+
if (!repoRoot) {
|
|
109
|
+
throw new Error('--repo "." requires harnery to be configured with repoRoot');
|
|
110
|
+
}
|
|
111
|
+
return [{ name: "parent", cwd: repoRoot }];
|
|
112
|
+
}
|
|
113
|
+
if (!submodules || !repoRoot) {
|
|
114
|
+
throw new Error(`--repo "${opts.repo}" requires harnery to be configured with repoRoot + submodules`);
|
|
115
|
+
}
|
|
116
|
+
const found = submodules.find((n) => n === opts.repo);
|
|
117
|
+
if (!found) {
|
|
118
|
+
throw new Error(`unknown repo "${opts.repo}". Valid: parent (.), ${submodules.join(", ")}`);
|
|
119
|
+
}
|
|
120
|
+
return [{ name: found, cwd: `${repoRoot}/${found}` }];
|
|
121
|
+
}
|
|
122
|
+
return [{ name: "cwd", cwd: process.cwd() }];
|
|
123
|
+
}
|
|
124
|
+
function grepInRepo(symbol, opts, repo, limit) {
|
|
125
|
+
const args = ["-rnw", "--color=never", "-I", "-E"];
|
|
126
|
+
for (const d of DEFAULT_EXCLUDE_DIRS)
|
|
127
|
+
args.push(`--exclude-dir=${d}`);
|
|
128
|
+
for (const f of DEFAULT_EXCLUDE_FILES)
|
|
129
|
+
args.push(`--exclude=${f}`);
|
|
130
|
+
const langGlobs = opts.lang ? LANG_GLOBS[opts.lang] : undefined;
|
|
131
|
+
if (opts.lang && !langGlobs) {
|
|
132
|
+
throw new Error(`unknown --lang "${opts.lang}". Valid: ${Object.keys(LANG_GLOBS).join(", ")}`);
|
|
133
|
+
}
|
|
134
|
+
if (langGlobs)
|
|
135
|
+
for (const g of langGlobs)
|
|
136
|
+
args.push(`--include=${g}`);
|
|
137
|
+
args.push("--", symbol, ".");
|
|
138
|
+
return new Promise((resolveP, reject) => {
|
|
139
|
+
const proc = spawn("grep", args, { cwd: repo.cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
140
|
+
const callers = [];
|
|
141
|
+
let buffer = "";
|
|
142
|
+
let stderr = "";
|
|
143
|
+
let truncated = false;
|
|
144
|
+
proc.stdout.setEncoding("utf8");
|
|
145
|
+
proc.stdout.on("data", (chunk) => {
|
|
146
|
+
if (truncated)
|
|
147
|
+
return;
|
|
148
|
+
buffer += chunk;
|
|
149
|
+
let nl = buffer.indexOf("\n");
|
|
150
|
+
while (nl >= 0) {
|
|
151
|
+
const line = buffer.slice(0, nl);
|
|
152
|
+
buffer = buffer.slice(nl + 1);
|
|
153
|
+
if (line.length !== 0) {
|
|
154
|
+
const parsed = parseCallerLine(line, symbol, opts, repo.name);
|
|
155
|
+
if (parsed)
|
|
156
|
+
callers.push(parsed);
|
|
157
|
+
if (callers.length >= limit) {
|
|
158
|
+
truncated = true;
|
|
159
|
+
proc.kill("SIGTERM");
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
nl = buffer.indexOf("\n");
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
proc.stderr.setEncoding("utf8");
|
|
167
|
+
proc.stderr.on("data", (chunk) => {
|
|
168
|
+
stderr += chunk;
|
|
169
|
+
});
|
|
170
|
+
proc.on("error", reject);
|
|
171
|
+
proc.on("close", (code) => {
|
|
172
|
+
if (buffer.length > 0 && !truncated) {
|
|
173
|
+
const parsed = parseCallerLine(buffer, symbol, opts, repo.name);
|
|
174
|
+
if (parsed)
|
|
175
|
+
callers.push(parsed);
|
|
176
|
+
}
|
|
177
|
+
if (code !== null && code !== 0 && code !== 1 && !truncated) {
|
|
178
|
+
reject(new Error(`grep exited ${code}: ${stderr.trim() || "(no stderr)"}`));
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
resolveP({ callers, truncated });
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
function parseCallerLine(line, symbol, opts, repoName) {
|
|
186
|
+
const firstColon = line.indexOf(":");
|
|
187
|
+
if (firstColon < 0)
|
|
188
|
+
return null;
|
|
189
|
+
const after = line.slice(firstColon + 1);
|
|
190
|
+
const secondColon = after.indexOf(":");
|
|
191
|
+
if (secondColon < 0)
|
|
192
|
+
return null;
|
|
193
|
+
const lineNum = Number.parseInt(after.slice(0, secondColon), 10);
|
|
194
|
+
if (!Number.isFinite(lineNum))
|
|
195
|
+
return null;
|
|
196
|
+
const file = line.slice(0, firstColon).replace(/^\.\//, "");
|
|
197
|
+
const text = after.slice(secondColon + 1);
|
|
198
|
+
if (!opts.includeComments) {
|
|
199
|
+
if (/^\s*(\/\/|#|--)/.test(text))
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
if (/^\s*\*[\s/]/.test(text))
|
|
203
|
+
return null; // /* multi-line comment continuation
|
|
204
|
+
const kind = classifyMatch(text, symbol);
|
|
205
|
+
if (kind === "decl" && !opts.includeDecl)
|
|
206
|
+
return null;
|
|
207
|
+
return { repo: repoName, file, line: lineNum, kind, text };
|
|
208
|
+
}
|
|
209
|
+
function classifyMatch(text, symbol) {
|
|
210
|
+
const sym = escapeRegex(symbol);
|
|
211
|
+
if (new RegExp(`^\\s*(export\\s+)?(async\\s+)?(function|class|interface|type|enum|namespace)\\s+${sym}\\b`).test(text)) {
|
|
212
|
+
return "decl";
|
|
213
|
+
}
|
|
214
|
+
if (new RegExp(`^\\s*(export\\s+)?(const|let|var)\\s+${sym}\\b`).test(text))
|
|
215
|
+
return "decl";
|
|
216
|
+
if (new RegExp(`^\\s*(public|private|protected)\\s+(static\\s+)?function\\s+${sym}\\b`).test(text)) {
|
|
217
|
+
return "decl";
|
|
218
|
+
}
|
|
219
|
+
if (new RegExp(`^\\s*(async\\s+)?def\\s+${sym}\\b`).test(text))
|
|
220
|
+
return "decl";
|
|
221
|
+
if (new RegExp(`^\\s*class\\s+${sym}\\b`).test(text))
|
|
222
|
+
return "decl";
|
|
223
|
+
if (/^\s*(import\b|from\b|use\s+|require\s*\(|include\s|require_once\s)/.test(text)) {
|
|
224
|
+
return "import";
|
|
225
|
+
}
|
|
226
|
+
if (new RegExp(`\\b${sym}\\s*\\(`).test(text))
|
|
227
|
+
return "call";
|
|
228
|
+
if (new RegExp(`(:\\s*${sym}\\b|extends\\s+${sym}\\b|implements\\s+${sym}\\b|as\\s+${sym}\\b|<${sym}[>\\s,])`).test(text)) {
|
|
229
|
+
return "type";
|
|
230
|
+
}
|
|
231
|
+
return "ref";
|
|
232
|
+
}
|
|
233
|
+
function escapeRegex(s) {
|
|
234
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
235
|
+
}
|
|
236
|
+
function renderCallers(r) {
|
|
237
|
+
const lines = [];
|
|
238
|
+
if (r.total === 0) {
|
|
239
|
+
lines.push(`callers · ${r.symbol}: no matches`);
|
|
240
|
+
return lines.join("\n");
|
|
241
|
+
}
|
|
242
|
+
const summary = Object.entries(r.by_kind)
|
|
243
|
+
.sort((a, b) => b[1] - a[1])
|
|
244
|
+
.map(([k, n]) => `${k}=${n}`)
|
|
245
|
+
.join(", ");
|
|
246
|
+
lines.push(`callers · ${r.symbol} (${r.total} total: ${summary}, ${r.elapsed_ms}ms)`);
|
|
247
|
+
const byRepo = new Map();
|
|
248
|
+
for (const c of r.callers) {
|
|
249
|
+
if (!byRepo.has(c.repo))
|
|
250
|
+
byRepo.set(c.repo, []);
|
|
251
|
+
byRepo.get(c.repo).push(c);
|
|
252
|
+
}
|
|
253
|
+
const showRepoHeader = byRepo.size > 1;
|
|
254
|
+
for (const [repo, callers] of byRepo) {
|
|
255
|
+
if (showRepoHeader) {
|
|
256
|
+
lines.push("");
|
|
257
|
+
lines.push(`── ${repo} (${callers.length}) ──`);
|
|
258
|
+
}
|
|
259
|
+
let lastFile = "";
|
|
260
|
+
for (const c of callers) {
|
|
261
|
+
if (c.file !== lastFile) {
|
|
262
|
+
lines.push("");
|
|
263
|
+
lines.push(` ${c.file}`);
|
|
264
|
+
lastFile = c.file;
|
|
265
|
+
}
|
|
266
|
+
const kindLabel = `[${c.kind}]`.padEnd(8);
|
|
267
|
+
const snippet = c.text.trim().slice(0, 100);
|
|
268
|
+
lines.push(` L${c.line.toString().padEnd(5)} ${kindLabel} ${snippet}`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
if (r.truncated) {
|
|
272
|
+
lines.push("");
|
|
273
|
+
lines.push("(truncated; pass --limit to widen)");
|
|
274
|
+
}
|
|
275
|
+
return lines.join("\n");
|
|
276
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import type { EmitContext, HarneryProgramContext } from "../commander.js";
|
|
3
|
+
/**
|
|
4
|
+
* `harn completion`: emit / install shell completion scripts.
|
|
5
|
+
*
|
|
6
|
+
* harn completion bash | zsh | fish → write generated script to stdout
|
|
7
|
+
* harn completion install [--shell ...] → install to the conventional location
|
|
8
|
+
*
|
|
9
|
+
* And the hidden internal entry point:
|
|
10
|
+
*
|
|
11
|
+
* harn __complete <provider> -- <partial>
|
|
12
|
+
* Called by the generated shell scripts at tab-time for dynamic-value
|
|
13
|
+
* completion. Returns newline-separated candidate values. Empty exit
|
|
14
|
+
* code 0 even on errors (don't disrupt the user's tab).
|
|
15
|
+
*/
|
|
16
|
+
export declare function registerCompletionCommand(program: Command, _emit: EmitContext, context?: HarneryProgramContext): void;
|
|
17
|
+
//# sourceMappingURL=completion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../src/commands/completion.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAY1E;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,WAAW,EAClB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,IAAI,CA8DN"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
import { generateBash, generateFish, generateZsh, walkProgram, } from "../lib/completion/index.js";
|
|
4
|
+
const noopProviderRunner = async () => [];
|
|
5
|
+
const noopLookup = () => undefined;
|
|
6
|
+
/**
|
|
7
|
+
* `harn completion`: emit / install shell completion scripts.
|
|
8
|
+
*
|
|
9
|
+
* harn completion bash | zsh | fish → write generated script to stdout
|
|
10
|
+
* harn completion install [--shell ...] → install to the conventional location
|
|
11
|
+
*
|
|
12
|
+
* And the hidden internal entry point:
|
|
13
|
+
*
|
|
14
|
+
* harn __complete <provider> -- <partial>
|
|
15
|
+
* Called by the generated shell scripts at tab-time for dynamic-value
|
|
16
|
+
* completion. Returns newline-separated candidate values. Empty exit
|
|
17
|
+
* code 0 even on errors (don't disrupt the user's tab).
|
|
18
|
+
*/
|
|
19
|
+
export function registerCompletionCommand(program, _emit, context) {
|
|
20
|
+
const lookup = context?.completionLookup ?? noopLookup;
|
|
21
|
+
const runProvider = context?.completionRunner ?? noopProviderRunner;
|
|
22
|
+
const root = program
|
|
23
|
+
.command("completion")
|
|
24
|
+
.description("Shell tab-completion. Emit a script per shell or install to the standard location.");
|
|
25
|
+
root
|
|
26
|
+
.command("bash")
|
|
27
|
+
.description("Emit bash completion script to stdout")
|
|
28
|
+
.action(() => {
|
|
29
|
+
const out = generateBash(walkProgram(program, lookup), program.name());
|
|
30
|
+
process.stdout.write(out); // raw bytes: shell completion scripts must be unframed (consumer evals stdout).
|
|
31
|
+
});
|
|
32
|
+
root
|
|
33
|
+
.command("zsh")
|
|
34
|
+
.description("Emit zsh completion script to stdout")
|
|
35
|
+
.action(() => {
|
|
36
|
+
const out = generateZsh(walkProgram(program, lookup), program.name());
|
|
37
|
+
process.stdout.write(out); // raw bytes: shell completion scripts must be unframed (consumer evals stdout).
|
|
38
|
+
});
|
|
39
|
+
root
|
|
40
|
+
.command("fish")
|
|
41
|
+
.description("Emit fish completion script to stdout")
|
|
42
|
+
.action(() => {
|
|
43
|
+
const out = generateFish(walkProgram(program, lookup), program.name());
|
|
44
|
+
process.stdout.write(out); // raw bytes: shell completion scripts must be unframed (consumer evals stdout).
|
|
45
|
+
});
|
|
46
|
+
root
|
|
47
|
+
.command("install")
|
|
48
|
+
.description("Write completion script to the conventional location for the chosen shell")
|
|
49
|
+
.option("--shell <name>", "bash | zsh | fish (default: auto-detect from $SHELL)")
|
|
50
|
+
.option("--path <file>", "Override destination path")
|
|
51
|
+
.option("--print-path", "Print the destination path and exit (no write)")
|
|
52
|
+
.action(async (opts) => {
|
|
53
|
+
await installCompletion(program, opts, lookup);
|
|
54
|
+
});
|
|
55
|
+
// Hidden internal entry: shells call this at tab-time. `hidden: true` so
|
|
56
|
+
// `harn --help` doesn't surface it.
|
|
57
|
+
const hidden = program
|
|
58
|
+
.command("__complete <provider> [partial]", { hidden: true })
|
|
59
|
+
.description("Internal: dynamic-value completion callback for the shell")
|
|
60
|
+
.allowExcessArguments(true)
|
|
61
|
+
.action(async (provider, partial) => {
|
|
62
|
+
try {
|
|
63
|
+
const values = await runProvider(provider, partial ?? "");
|
|
64
|
+
for (const v of values) {
|
|
65
|
+
process.stdout.write(`${v}\n`); // lint-ok-emission: shell callback; newline-delimited raw values is the contract with compgen/_describe/fish.
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// Swallow errors silently: failure during tab completion should not
|
|
70
|
+
// break the user's shell.
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
// Keep TS happy that the variable is used.
|
|
74
|
+
void hidden;
|
|
75
|
+
}
|
|
76
|
+
async function installCompletion(program, opts, lookup) {
|
|
77
|
+
const shell = opts.shell ?? detectShell();
|
|
78
|
+
if (!shell) {
|
|
79
|
+
process.stderr.write("Could not auto-detect shell. Pass --shell bash|zsh|fish explicitly.\n"); // lint-ok-emission: install error; stderr keeps stdout clean for --print-path piping.
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
const destination = opts.path ?? defaultInstallPath(shell, program.name());
|
|
83
|
+
if (opts.printPath) {
|
|
84
|
+
process.stdout.write(`${destination}\n`); // lint-ok-emission: --print-path is meant to be piped (e.g., dest=$(harn completion install --print-path)).
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
let content;
|
|
88
|
+
switch (shell) {
|
|
89
|
+
case "bash":
|
|
90
|
+
content = generateBash(walkProgram(program, lookup), program.name());
|
|
91
|
+
break;
|
|
92
|
+
case "zsh":
|
|
93
|
+
content = generateZsh(walkProgram(program, lookup), program.name());
|
|
94
|
+
break;
|
|
95
|
+
case "fish":
|
|
96
|
+
content = generateFish(walkProgram(program, lookup), program.name());
|
|
97
|
+
break;
|
|
98
|
+
default:
|
|
99
|
+
process.stderr.write(`Unknown shell: ${shell}\n`); // lint-ok-emission: install-time error, see above.
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
mkdirSync(dirname(destination), { recursive: true });
|
|
103
|
+
writeFileSync(destination, content);
|
|
104
|
+
process.stderr.write(`Installed ${shell} completion to ${destination}\n`); // lint-ok-emission: install progress; stderr keeps stdout clean.
|
|
105
|
+
// Hint how to activate.
|
|
106
|
+
printActivationHint(shell, destination);
|
|
107
|
+
}
|
|
108
|
+
function detectShell() {
|
|
109
|
+
const shellPath = process.env.SHELL ?? "";
|
|
110
|
+
if (shellPath.endsWith("/bash"))
|
|
111
|
+
return "bash";
|
|
112
|
+
if (shellPath.endsWith("/zsh"))
|
|
113
|
+
return "zsh";
|
|
114
|
+
if (shellPath.endsWith("/fish"))
|
|
115
|
+
return "fish";
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
function defaultInstallPath(shell, binName) {
|
|
119
|
+
const home = process.env.HOME ?? "";
|
|
120
|
+
switch (shell) {
|
|
121
|
+
case "bash": {
|
|
122
|
+
// bash-completion v2 user-level location.
|
|
123
|
+
const xdg = process.env.XDG_DATA_HOME ?? resolve(home, ".local/share");
|
|
124
|
+
return resolve(xdg, `bash-completion/completions/${binName}`);
|
|
125
|
+
}
|
|
126
|
+
case "zsh": {
|
|
127
|
+
// Common $fpath user location. zsh auto-loads from ~/.zsh/completions if
|
|
128
|
+
// it's in $fpath.
|
|
129
|
+
return resolve(home, `.zsh/completions/_${binName}`);
|
|
130
|
+
}
|
|
131
|
+
case "fish": {
|
|
132
|
+
// Fish auto-loads everything in ~/.config/fish/completions/.
|
|
133
|
+
return resolve(home, `.config/fish/completions/${binName}.fish`);
|
|
134
|
+
}
|
|
135
|
+
default:
|
|
136
|
+
return resolve(home, `.${binName}-completion.${shell}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function printActivationHint(shell, path) {
|
|
140
|
+
switch (shell) {
|
|
141
|
+
case "bash":
|
|
142
|
+
if (existsSync(resolve(process.env.HOME ?? "", ".bashrc"))) {
|
|
143
|
+
const bashHint = `\nTo activate now in this shell: source "${path}"\nNew shells will pick it up automatically if bash-completion is enabled.\nIf completions don't fire in new shells, add this to ~/.bashrc:\n [ -f "${path}" ] && source "${path}"\n`;
|
|
144
|
+
process.stderr.write(bashHint); // lint-ok-emission: post-install activation hint; stderr keeps stdout clean.
|
|
145
|
+
}
|
|
146
|
+
break;
|
|
147
|
+
case "zsh": {
|
|
148
|
+
const zshHint = `\nTo activate now: autoload -U compinit && compinit\nMake sure ${resolve(path, "..")} is in your $fpath. Add to ~/.zshrc:\n fpath=(${resolve(path, "..")} $fpath)\n autoload -U compinit && compinit\n`;
|
|
149
|
+
process.stderr.write(zshHint); // lint-ok-emission: post-install activation hint; stderr keeps stdout clean.
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
case "fish": {
|
|
153
|
+
const fishHint = `\nFish auto-loads completions from ${resolve(path, "..")}. New shells pick it up.\nTo activate now: source "${path}"\n`;
|
|
154
|
+
process.stderr.write(fishHint); // lint-ok-emission: post-install activation hint; stderr keeps stdout clean.
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-get.d.ts","sourceRoot":"","sources":["../../src/commands/config-get.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAuBnD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CA2BlF"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { extname, resolve } from "node:path";
|
|
3
|
+
import yaml from "js-yaml";
|
|
4
|
+
export function registerConfigGetCommand(program, emit) {
|
|
5
|
+
program
|
|
6
|
+
.command("config-get <file> <key>")
|
|
7
|
+
.description("Extract a single value from a JSON/YAML config file by dotted-path. " +
|
|
8
|
+
"Bracket notation supported: `config-get tsconfig.json compilerOptions.paths`.")
|
|
9
|
+
.option("--json", "Structured JSON envelope {file, format, key, value, type, found}")
|
|
10
|
+
.option("--raw", "Print raw string value (no JSON encoding wrapper)")
|
|
11
|
+
.action(async (file, key, opts) => {
|
|
12
|
+
try {
|
|
13
|
+
const result = await runConfigGet(file, key);
|
|
14
|
+
if (opts.json) {
|
|
15
|
+
emit.config({ format: "json" });
|
|
16
|
+
emit.data(result);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (!result.found) {
|
|
20
|
+
emit.error({ code: "key_not_found", message: `key "${key}" not found in ${file}` });
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
emit.text(`${renderValue(result.value)}\n`);
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
emit.error({ code: "config_get_failed", message: err.message });
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
async function runConfigGet(file, key) {
|
|
32
|
+
const absPath = resolve(file);
|
|
33
|
+
if (!existsSync(absPath))
|
|
34
|
+
throw new Error(`no such file: ${file}`);
|
|
35
|
+
const content = readFileSync(absPath, "utf8");
|
|
36
|
+
const ext = extname(absPath).toLowerCase();
|
|
37
|
+
let format;
|
|
38
|
+
let parsed;
|
|
39
|
+
if (ext === ".json") {
|
|
40
|
+
format = "json";
|
|
41
|
+
try {
|
|
42
|
+
parsed = JSON.parse(content);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
throw new Error(`json parse failed: ${err.message}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else if (ext === ".yaml" || ext === ".yml") {
|
|
49
|
+
format = "yaml";
|
|
50
|
+
try {
|
|
51
|
+
parsed = yaml.load(content);
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
throw new Error(`yaml parse failed: ${err.message}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
throw new Error(`unsupported file type: ${ext || "(no extension)"} (supported: .json, .yaml, .yml)`);
|
|
59
|
+
}
|
|
60
|
+
const parts = parseDottedPath(key);
|
|
61
|
+
let cur = parsed;
|
|
62
|
+
let found = true;
|
|
63
|
+
for (const p of parts) {
|
|
64
|
+
if (cur == null || typeof cur !== "object") {
|
|
65
|
+
found = false;
|
|
66
|
+
cur = undefined;
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
const obj = cur;
|
|
70
|
+
if (!(p in obj)) {
|
|
71
|
+
found = false;
|
|
72
|
+
cur = undefined;
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
cur = obj[p];
|
|
76
|
+
}
|
|
77
|
+
const type = cur === null
|
|
78
|
+
? "null"
|
|
79
|
+
: Array.isArray(cur)
|
|
80
|
+
? "array"
|
|
81
|
+
: cur === undefined
|
|
82
|
+
? "undefined"
|
|
83
|
+
: typeof cur;
|
|
84
|
+
return {
|
|
85
|
+
file,
|
|
86
|
+
format,
|
|
87
|
+
key,
|
|
88
|
+
value: cur,
|
|
89
|
+
type,
|
|
90
|
+
found,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function parseDottedPath(path) {
|
|
94
|
+
const parts = [];
|
|
95
|
+
let i = 0;
|
|
96
|
+
while (i < path.length) {
|
|
97
|
+
if (path[i] === ".") {
|
|
98
|
+
i++;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (path[i] === "[") {
|
|
102
|
+
const end = path.indexOf("]", i);
|
|
103
|
+
if (end < 0)
|
|
104
|
+
throw new Error(`unmatched [ in key: ${path}`);
|
|
105
|
+
let inner = path.slice(i + 1, end);
|
|
106
|
+
if ((inner.startsWith('"') && inner.endsWith('"')) ||
|
|
107
|
+
(inner.startsWith("'") && inner.endsWith("'"))) {
|
|
108
|
+
inner = inner.slice(1, -1);
|
|
109
|
+
}
|
|
110
|
+
parts.push(inner);
|
|
111
|
+
i = end + 1;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
let end = i;
|
|
115
|
+
while (end < path.length && path[end] !== "." && path[end] !== "[")
|
|
116
|
+
end++;
|
|
117
|
+
parts.push(path.slice(i, end));
|
|
118
|
+
i = end;
|
|
119
|
+
}
|
|
120
|
+
return parts;
|
|
121
|
+
}
|
|
122
|
+
function renderValue(value) {
|
|
123
|
+
if (value === undefined)
|
|
124
|
+
return "";
|
|
125
|
+
if (typeof value === "string")
|
|
126
|
+
return value;
|
|
127
|
+
if (value === null || typeof value === "boolean" || typeof value === "number") {
|
|
128
|
+
return String(value);
|
|
129
|
+
}
|
|
130
|
+
return JSON.stringify(value, null, 2);
|
|
131
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import type { EmitContext, HarneryProgramContext } from "../commander.js";
|
|
3
|
+
/**
|
|
4
|
+
* `harn context`: one-shot orientation snapshot.
|
|
5
|
+
*
|
|
6
|
+
* Aggregates self / time / repo / commits / submodules / peers (default) plus
|
|
7
|
+
* opt-in services. Useful at session start, post-compaction, or before
|
|
8
|
+
* dispatching subagents. Fail-open per section.
|
|
9
|
+
*/
|
|
10
|
+
export declare function registerContextCommand(program: Command, emit: EmitContext, context?: HarneryProgramContext): void;
|
|
11
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/commands/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAS1E;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,WAAW,EACjB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,IAAI,CAiDN"}
|