ctxr-cli 0.33.0 → 0.35.0
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/README.md +40 -6
- package/dist/commands/archive.d.ts +5 -4
- package/dist/commands/archive.d.ts.map +1 -1
- package/dist/commands/archive.js +7 -7
- package/dist/commands/archive.js.map +1 -1
- package/dist/commands/catalog-show.d.ts +8 -0
- package/dist/commands/catalog-show.d.ts.map +1 -1
- package/dist/commands/catalog-show.js +29 -2
- package/dist/commands/catalog-show.js.map +1 -1
- package/dist/commands/context-gather.d.ts.map +1 -1
- package/dist/commands/context-gather.js +3 -2
- package/dist/commands/context-gather.js.map +1 -1
- package/dist/commands/doctor.d.ts +5 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +4 -0
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/graph-build.d.ts +4 -1
- package/dist/commands/graph-build.d.ts.map +1 -1
- package/dist/commands/graph-build.js +14 -5
- package/dist/commands/graph-build.js.map +1 -1
- package/dist/commands/land.d.ts +27 -7
- package/dist/commands/land.d.ts.map +1 -1
- package/dist/commands/land.js +307 -32
- package/dist/commands/land.js.map +1 -1
- package/dist/commands/plugin-build.d.ts +33 -0
- package/dist/commands/plugin-build.d.ts.map +1 -0
- package/dist/commands/plugin-build.js +51 -0
- package/dist/commands/plugin-build.js.map +1 -0
- package/dist/commands/publish-check.d.ts.map +1 -1
- package/dist/commands/publish-check.js +35 -4
- package/dist/commands/publish-check.js.map +1 -1
- package/dist/commands/publish-gather.d.ts.map +1 -1
- package/dist/commands/publish-gather.js +2 -3
- package/dist/commands/publish-gather.js.map +1 -1
- package/dist/commands/review-list.d.ts +19 -5
- package/dist/commands/review-list.d.ts.map +1 -1
- package/dist/commands/review-list.js +55 -6
- package/dist/commands/review-list.js.map +1 -1
- package/dist/commands/rollup-gather.d.ts.map +1 -1
- package/dist/commands/rollup-gather.js +2 -3
- package/dist/commands/rollup-gather.js.map +1 -1
- package/dist/commands/second-opinion.d.ts +33 -0
- package/dist/commands/second-opinion.d.ts.map +1 -0
- package/dist/commands/second-opinion.js +56 -0
- package/dist/commands/second-opinion.js.map +1 -0
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/commands/serve.js +14 -2
- package/dist/commands/serve.js.map +1 -1
- package/dist/commands/session-discard.d.ts +18 -0
- package/dist/commands/session-discard.d.ts.map +1 -0
- package/dist/commands/session-discard.js +31 -0
- package/dist/commands/session-discard.js.map +1 -0
- package/dist/commands/session-list.d.ts +17 -6
- package/dist/commands/session-list.d.ts.map +1 -1
- package/dist/commands/session-list.js +31 -11
- package/dist/commands/session-list.js.map +1 -1
- package/dist/commands/session-rebase.d.ts +18 -0
- package/dist/commands/session-rebase.d.ts.map +1 -0
- package/dist/commands/session-rebase.js +43 -0
- package/dist/commands/session-rebase.js.map +1 -0
- package/dist/commands/session-start.d.ts +8 -0
- package/dist/commands/session-start.d.ts.map +1 -1
- package/dist/commands/session-start.js +52 -38
- package/dist/commands/session-start.js.map +1 -1
- package/dist/commands/session-status.d.ts +17 -0
- package/dist/commands/session-status.d.ts.map +1 -0
- package/dist/commands/session-status.js +38 -0
- package/dist/commands/session-status.js.map +1 -0
- package/dist/commands/session-submit.d.ts +23 -0
- package/dist/commands/session-submit.d.ts.map +1 -0
- package/dist/commands/session-submit.js +42 -0
- package/dist/commands/session-submit.js.map +1 -0
- package/dist/commands/shared-stores-status.d.ts +24 -0
- package/dist/commands/shared-stores-status.d.ts.map +1 -0
- package/dist/commands/shared-stores-status.js +51 -0
- package/dist/commands/shared-stores-status.js.map +1 -0
- package/dist/commands/shared-stores-sync.d.ts +27 -0
- package/dist/commands/shared-stores-sync.d.ts.map +1 -0
- package/dist/commands/shared-stores-sync.js +115 -0
- package/dist/commands/shared-stores-sync.js.map +1 -0
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +2 -4
- package/dist/commands/verify.js.map +1 -1
- package/dist/config/schema.d.ts +16 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +32 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/core/agents-doc.d.ts +10 -0
- package/dist/core/agents-doc.d.ts.map +1 -1
- package/dist/core/agents-doc.js +26 -1
- package/dist/core/agents-doc.js.map +1 -1
- package/dist/core/approval/decision.d.ts +39 -1
- package/dist/core/approval/decision.d.ts.map +1 -1
- package/dist/core/approval/decision.js +53 -6
- package/dist/core/approval/decision.js.map +1 -1
- package/dist/core/approval/session-group.d.ts +156 -0
- package/dist/core/approval/session-group.d.ts.map +1 -0
- package/dist/core/approval/session-group.js +359 -0
- package/dist/core/approval/session-group.js.map +1 -0
- package/dist/core/approval/session-marker.d.ts +79 -0
- package/dist/core/approval/session-marker.d.ts.map +1 -0
- package/dist/core/approval/session-marker.js +146 -0
- package/dist/core/approval/session-marker.js.map +1 -0
- package/dist/core/approval/store-forges.d.ts +15 -0
- package/dist/core/approval/store-forges.d.ts.map +1 -0
- package/dist/core/approval/store-forges.js +33 -0
- package/dist/core/approval/store-forges.js.map +1 -0
- package/dist/core/browse/approve.d.ts +8 -0
- package/dist/core/browse/approve.d.ts.map +1 -1
- package/dist/core/browse/approve.js +366 -48
- package/dist/core/browse/approve.js.map +1 -1
- package/dist/core/browse/link-resolver.d.ts +9 -4
- package/dist/core/browse/link-resolver.d.ts.map +1 -1
- package/dist/core/browse/link-resolver.js +12 -7
- package/dist/core/browse/link-resolver.js.map +1 -1
- package/dist/core/browse/review.d.ts +5 -0
- package/dist/core/browse/review.d.ts.map +1 -1
- package/dist/core/browse/review.js +8 -0
- package/dist/core/browse/review.js.map +1 -1
- package/dist/core/checks/integrity-checks.d.ts.map +1 -1
- package/dist/core/checks/integrity-checks.js +7 -1
- package/dist/core/checks/integrity-checks.js.map +1 -1
- package/dist/core/checks/manifest.d.ts.map +1 -1
- package/dist/core/checks/manifest.js +2 -0
- package/dist/core/checks/manifest.js.map +1 -1
- package/dist/core/checks/shared-stores-checks.d.ts +17 -0
- package/dist/core/checks/shared-stores-checks.d.ts.map +1 -0
- package/dist/core/checks/shared-stores-checks.js +84 -0
- package/dist/core/checks/shared-stores-checks.js.map +1 -0
- package/dist/core/errors.d.ts +17 -0
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +21 -0
- package/dist/core/errors.js.map +1 -1
- package/dist/core/forge/github.d.ts +14 -0
- package/dist/core/forge/github.d.ts.map +1 -1
- package/dist/core/forge/github.js +17 -0
- package/dist/core/forge/github.js.map +1 -1
- package/dist/core/fs/atomic.d.ts +3 -2
- package/dist/core/fs/atomic.d.ts.map +1 -1
- package/dist/core/fs/atomic.js +3 -2
- package/dist/core/fs/atomic.js.map +1 -1
- package/dist/core/git/fast-forward.d.ts +23 -0
- package/dist/core/git/fast-forward.d.ts.map +1 -0
- package/dist/core/git/fast-forward.js +38 -0
- package/dist/core/git/fast-forward.js.map +1 -0
- package/dist/core/git/repo.d.ts +11 -0
- package/dist/core/git/repo.d.ts.map +1 -1
- package/dist/core/git/repo.js +25 -0
- package/dist/core/git/repo.js.map +1 -1
- package/dist/core/graph/model.d.ts +27 -0
- package/dist/core/graph/model.d.ts.map +1 -1
- package/dist/core/graph/model.js +68 -2
- package/dist/core/graph/model.js.map +1 -1
- package/dist/core/graph/persist.d.ts.map +1 -1
- package/dist/core/graph/persist.js +3 -2
- package/dist/core/graph/persist.js.map +1 -1
- package/dist/core/mcp/cli-runner.d.ts +41 -0
- package/dist/core/mcp/cli-runner.d.ts.map +1 -0
- package/dist/core/mcp/cli-runner.js +81 -0
- package/dist/core/mcp/cli-runner.js.map +1 -0
- package/dist/core/mcp/jsonrpc.d.ts +13 -1
- package/dist/core/mcp/jsonrpc.d.ts.map +1 -1
- package/dist/core/mcp/jsonrpc.js +1 -1
- package/dist/core/mcp/jsonrpc.js.map +1 -1
- package/dist/core/mcp/member-sessions.d.ts +48 -0
- package/dist/core/mcp/member-sessions.d.ts.map +1 -0
- package/dist/core/mcp/member-sessions.js +85 -0
- package/dist/core/mcp/member-sessions.js.map +1 -0
- package/dist/core/mcp/ownership.d.ts +51 -0
- package/dist/core/mcp/ownership.d.ts.map +1 -0
- package/dist/core/mcp/ownership.js +101 -0
- package/dist/core/mcp/ownership.js.map +1 -0
- package/dist/core/mcp/paths.d.ts +48 -0
- package/dist/core/mcp/paths.d.ts.map +1 -0
- package/dist/core/mcp/paths.js +111 -0
- package/dist/core/mcp/paths.js.map +1 -0
- package/dist/core/mcp/sessions.d.ts +25 -50
- package/dist/core/mcp/sessions.d.ts.map +1 -1
- package/dist/core/mcp/sessions.js +31 -123
- package/dist/core/mcp/sessions.js.map +1 -1
- package/dist/core/mcp/tool-map.d.ts +94 -0
- package/dist/core/mcp/tool-map.d.ts.map +1 -0
- package/dist/core/mcp/tool-map.js +211 -0
- package/dist/core/mcp/tool-map.js.map +1 -0
- package/dist/core/mcp/tools/capture.d.ts +7 -2
- package/dist/core/mcp/tools/capture.d.ts.map +1 -1
- package/dist/core/mcp/tools/capture.js +69 -18
- package/dist/core/mcp/tools/capture.js.map +1 -1
- package/dist/core/mcp/tools/cli.d.ts +97 -0
- package/dist/core/mcp/tools/cli.d.ts.map +1 -0
- package/dist/core/mcp/tools/cli.js +271 -0
- package/dist/core/mcp/tools/cli.js.map +1 -0
- package/dist/core/mcp/tools/edit.d.ts +62 -28
- package/dist/core/mcp/tools/edit.d.ts.map +1 -1
- package/dist/core/mcp/tools/edit.js +182 -153
- package/dist/core/mcp/tools/edit.js.map +1 -1
- package/dist/core/mcp/tools/files.d.ts +37 -11
- package/dist/core/mcp/tools/files.d.ts.map +1 -1
- package/dist/core/mcp/tools/files.js +122 -100
- package/dist/core/mcp/tools/files.js.map +1 -1
- package/dist/core/mcp/tools/index.d.ts +12 -3
- package/dist/core/mcp/tools/index.d.ts.map +1 -1
- package/dist/core/mcp/tools/index.js +161 -58
- package/dist/core/mcp/tools/index.js.map +1 -1
- package/dist/core/mcp/tools/sessions.d.ts +145 -0
- package/dist/core/mcp/tools/sessions.d.ts.map +1 -0
- package/dist/core/mcp/tools/sessions.js +226 -0
- package/dist/core/mcp/tools/sessions.js.map +1 -0
- package/dist/core/notes/list.d.ts.map +1 -1
- package/dist/core/notes/list.js +5 -0
- package/dist/core/notes/list.js.map +1 -1
- package/dist/core/plugin/build.d.ts +70 -0
- package/dist/core/plugin/build.d.ts.map +1 -0
- package/dist/core/plugin/build.js +159 -0
- package/dist/core/plugin/build.js.map +1 -0
- package/dist/core/plugin/routes.d.ts +35 -0
- package/dist/core/plugin/routes.d.ts.map +1 -0
- package/dist/core/plugin/routes.js +77 -0
- package/dist/core/plugin/routes.js.map +1 -0
- package/dist/core/plugin/zip.d.ts +17 -0
- package/dist/core/plugin/zip.d.ts.map +1 -0
- package/dist/core/plugin/zip.js +75 -0
- package/dist/core/plugin/zip.js.map +1 -0
- package/dist/core/reconcile.d.ts.map +1 -1
- package/dist/core/reconcile.js +2 -1
- package/dist/core/reconcile.js.map +1 -1
- package/dist/core/retrieval/pass.d.ts.map +1 -1
- package/dist/core/retrieval/pass.js +5 -4
- package/dist/core/retrieval/pass.js.map +1 -1
- package/dist/core/rollup.d.ts.map +1 -1
- package/dist/core/rollup.js +2 -3
- package/dist/core/rollup.js.map +1 -1
- package/dist/core/root.d.ts.map +1 -1
- package/dist/core/root.js +33 -2
- package/dist/core/root.js.map +1 -1
- package/dist/core/second-opinion/environment.d.ts +21 -0
- package/dist/core/second-opinion/environment.d.ts.map +1 -0
- package/dist/core/second-opinion/environment.js +70 -0
- package/dist/core/second-opinion/environment.js.map +1 -0
- package/dist/core/second-opinion/judge.d.ts +29 -0
- package/dist/core/second-opinion/judge.d.ts.map +1 -0
- package/dist/core/second-opinion/judge.js +55 -0
- package/dist/core/second-opinion/judge.js.map +1 -0
- package/dist/core/second-opinion/launch.d.ts +16 -0
- package/dist/core/second-opinion/launch.d.ts.map +1 -0
- package/dist/core/second-opinion/launch.js +75 -0
- package/dist/core/second-opinion/launch.js.map +1 -0
- package/dist/core/second-opinion/lineup.d.ts +82 -0
- package/dist/core/second-opinion/lineup.d.ts.map +1 -0
- package/dist/core/second-opinion/lineup.js +113 -0
- package/dist/core/second-opinion/lineup.js.map +1 -0
- package/dist/core/second-opinion/modes.d.ts +98 -0
- package/dist/core/second-opinion/modes.d.ts.map +1 -0
- package/dist/core/second-opinion/modes.js +224 -0
- package/dist/core/second-opinion/modes.js.map +1 -0
- package/dist/core/second-opinion/prompts.d.ts +18 -0
- package/dist/core/second-opinion/prompts.d.ts.map +1 -0
- package/dist/core/second-opinion/prompts.js +65 -0
- package/dist/core/second-opinion/prompts.js.map +1 -0
- package/dist/core/session/commit.d.ts +29 -0
- package/dist/core/session/commit.d.ts.map +1 -0
- package/dist/core/session/commit.js +22 -0
- package/dist/core/session/commit.js.map +1 -0
- package/dist/core/session/discard.d.ts +24 -0
- package/dist/core/session/discard.d.ts.map +1 -0
- package/dist/core/session/discard.js +68 -0
- package/dist/core/session/discard.js.map +1 -0
- package/dist/core/session/list.d.ts +48 -0
- package/dist/core/session/list.d.ts.map +1 -0
- package/dist/core/session/list.js +55 -0
- package/dist/core/session/list.js.map +1 -0
- package/dist/core/session/rebase.d.ts +34 -0
- package/dist/core/session/rebase.d.ts.map +1 -0
- package/dist/core/session/rebase.js +87 -0
- package/dist/core/session/rebase.js.map +1 -0
- package/dist/core/session/remote.d.ts +80 -0
- package/dist/core/session/remote.d.ts.map +1 -0
- package/dist/core/session/remote.js +102 -0
- package/dist/core/session/remote.js.map +1 -0
- package/dist/core/session/resolve.d.ts +41 -0
- package/dist/core/session/resolve.d.ts.map +1 -0
- package/dist/core/session/resolve.js +109 -0
- package/dist/core/session/resolve.js.map +1 -0
- package/dist/core/session/start.d.ts +46 -0
- package/dist/core/session/start.d.ts.map +1 -0
- package/dist/core/session/start.js +33 -0
- package/dist/core/session/start.js.map +1 -0
- package/dist/core/session/status.d.ts +47 -0
- package/dist/core/session/status.d.ts.map +1 -0
- package/dist/core/session/status.js +55 -0
- package/dist/core/session/status.js.map +1 -0
- package/dist/core/session/submit.d.ts +67 -0
- package/dist/core/session/submit.d.ts.map +1 -0
- package/dist/core/session/submit.js +254 -0
- package/dist/core/session/submit.js.map +1 -0
- package/dist/core/shared-stores-location.d.ts +17 -0
- package/dist/core/shared-stores-location.d.ts.map +1 -0
- package/dist/core/shared-stores-location.js +22 -0
- package/dist/core/shared-stores-location.js.map +1 -0
- package/dist/core/shared-stores.d.ts +69 -0
- package/dist/core/shared-stores.d.ts.map +1 -0
- package/dist/core/shared-stores.js +100 -0
- package/dist/core/shared-stores.js.map +1 -0
- package/dist/core/skills.d.ts +20 -2
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +70 -13
- package/dist/core/skills.js.map +1 -1
- package/dist/run.d.ts +12 -0
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +194 -55
- package/dist/run.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/templates/agents/shared-stores.md +11 -0
- package/templates/approve/copies-missing.md +1 -0
- package/templates/approve/elsewhere-heading.md +1 -0
- package/templates/approve/elsewhere-intro.md +1 -0
- package/templates/approve/homed-elsewhere.md +1 -0
- package/templates/approve/not-decider.md +1 -0
- package/templates/approve/part-heading.md +1 -0
- package/templates/approve/parts-changed.md +1 -0
- package/templates/approve/session-decision-note.md +1 -0
- package/templates/approve/session-intro.md +1 -0
- package/templates/approve/session-no-decision.md +1 -0
- package/templates/approve/store-unreachable.md +1 -0
- package/templates/land/resolver.md +2 -0
- package/templates/mcp/Delete.md +6 -0
- package/templates/mcp/Edit.md +6 -5
- package/templates/mcp/Glob.md +2 -2
- package/templates/mcp/Grep.md +2 -1
- package/templates/mcp/Move.md +7 -0
- package/templates/mcp/Read.md +4 -4
- package/templates/mcp/Write.md +4 -4
- package/templates/mcp/ctxr.md +7 -0
- package/templates/mcp/ctxr_write.md +8 -0
- package/templates/mcp/server-instructions.md +11 -3
- package/templates/mcp/session_discard.md +4 -0
- package/templates/mcp/session_list.md +7 -0
- package/templates/mcp/session_rebase.md +5 -0
- package/templates/mcp/session_start.md +7 -0
- package/templates/mcp/session_status.md +3 -0
- package/templates/mcp/session_submit.md +8 -0
- package/templates/plugin/README.md +13 -0
- package/templates/plugin/chatgpt-mcp.json +19 -0
- package/templates/plugin/chatgpt-plugin.json +13 -0
- package/templates/plugin/claude-mcp.json +8 -0
- package/templates/plugin/claude-plugin.json +6 -0
- package/templates/plugin/page.html +47 -0
- package/templates/second-opinion/poll-answer.md +7 -0
- package/templates/second-opinion/taste-panel.md +14 -0
- package/templates/session/pages/bare-route.md +2 -0
- package/templates/session/pages/block.md +8 -0
- package/templates/session/pages/condition-preview.md +1 -0
- package/templates/session/pages/condition.md +1 -0
- package/templates/session/pages/moved.md +1 -0
- package/templates/session/pages/stops-working.md +1 -0
- package/templates/session/pages/table-head-preview.md +2 -0
- package/templates/session/pages/table-head.md +2 -0
- package/templates/skills/ctxr-connection-finding.md +4 -1
- package/templates/skills/ctxr-land.md +26 -7
- package/templates/skills/ctxr-placement.md +10 -0
- package/templates/skills/ctxr-publish.md +2 -1
- package/templates/skills/ctxr-rollup.md +3 -0
- package/templates/skills/ctxr-second-opinion.md +52 -36
- package/templates/skills/ctxr-session-lifecycle.md +60 -33
- package/templates/skills/ctxr-submit.md +65 -56
- package/templates/skills/mcp/_preamble.md +44 -0
- package/dist/core/mcp/drafts.d.ts +0 -30
- package/dist/core/mcp/drafts.d.ts.map +0 -1
- package/dist/core/mcp/drafts.js +0 -52
- package/dist/core/mcp/drafts.js.map +0 -1
- package/templates/skills/ctxr-second-opinion/run.mjs +0 -542
- /package/templates/{skills/ctxr-second-opinion → second-opinion}/critic-contract.md +0 -0
- /package/templates/{skills/ctxr-second-opinion → second-opinion}/lenses.md +0 -0
- /package/templates/{skills/ctxr-second-opinion → second-opinion}/personas/architect.md +0 -0
- /package/templates/{skills/ctxr-second-opinion → second-opinion}/personas/pragmatist.md +0 -0
- /package/templates/{skills/ctxr-second-opinion → second-opinion}/personas/skeptic.md +0 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { ContextureError } from '../../errors.js';
|
|
2
|
+
import { discardSession } from '../../session/discard.js';
|
|
3
|
+
import { listSessions } from '../../session/list.js';
|
|
4
|
+
import { rebaseSession } from '../../session/rebase.js';
|
|
5
|
+
import { rebaseInProgress } from '../../session/resolve.js';
|
|
6
|
+
import { sessionStatus } from '../../session/status.js';
|
|
7
|
+
import { submitSession } from '../../session/submit.js';
|
|
8
|
+
import { sessionLabelFromDirName } from '../../session.js';
|
|
9
|
+
import { ToolRefusal } from '../jsonrpc.js';
|
|
10
|
+
import { memberSessions, ownedSession, ownershipOf, repoPrefixOf, sessionRootFor } from '../member-sessions.js';
|
|
11
|
+
import { MAX_OPEN_SESSIONS } from '../ownership.js';
|
|
12
|
+
import { approvalUrl, memberCommit, startSession } from '../sessions.js';
|
|
13
|
+
/**
|
|
14
|
+
* serve-the-session-lifecycle-to-chat-apps D3 (remote-access spec, *A member
|
|
15
|
+
* works in named sessions of their own*, *`session_submit` validates, commits
|
|
16
|
+
* as the member and opens the pull request*, *A member's session can be
|
|
17
|
+
* rebased or discarded*): one tool per `ctxr session <verb>`, each calling the
|
|
18
|
+
* same core the command calls, with the command's options as fields. The MCP
|
|
19
|
+
* layer adds the ownership check, the member as commit author, and the
|
|
20
|
+
* confinement to sessions started over MCP. Server paths never leave: a
|
|
21
|
+
* session is named by its directory and addressed by its store-relative root.
|
|
22
|
+
*/
|
|
23
|
+
/** D3: `session_status`'s unified diff is bounded to this many bytes. */
|
|
24
|
+
export const STATUS_DIFF_MAX_BYTES = 100 * 1024;
|
|
25
|
+
const invalid = (message) => new ToolRefusal('mcp.invalid_arguments', message);
|
|
26
|
+
function optionalString(args, key) {
|
|
27
|
+
const value = args[key];
|
|
28
|
+
if (value === undefined || value === null)
|
|
29
|
+
return undefined;
|
|
30
|
+
if (typeof value !== 'string')
|
|
31
|
+
throw invalid(`"${key}" must be a string.`);
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
function requiredString(args, key) {
|
|
35
|
+
const value = optionalString(args, key);
|
|
36
|
+
if (value === undefined || value.trim() === '')
|
|
37
|
+
throw invalid(`"${key}" is required.`);
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
function optionalBoolean(args, key) {
|
|
41
|
+
const value = args[key];
|
|
42
|
+
if (value === undefined || value === null)
|
|
43
|
+
return false;
|
|
44
|
+
if (typeof value !== 'boolean')
|
|
45
|
+
throw invalid(`"${key}" must be true or false.`);
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
48
|
+
const SESSION_PROPERTY = { type: 'string', description: 'The session\'s directory name, as session_start or session_list gave it.' };
|
|
49
|
+
// ---- session_start --------------------------------------------------------------
|
|
50
|
+
export const SESSION_START_INPUT_SCHEMA = {
|
|
51
|
+
type: 'object',
|
|
52
|
+
properties: {
|
|
53
|
+
label: { type: 'string', description: 'A short name for what the session is for, e.g. "kestrel-launch"; it becomes part of the branch and directory name. Optional.' },
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
/** Under the write mutex. */
|
|
57
|
+
export async function sessionStartTool(write, email, args) {
|
|
58
|
+
const label = optionalString(args, 'label');
|
|
59
|
+
const open = (await memberSessions(write, email)).filter((s) => s.kind === 'session');
|
|
60
|
+
if (open.length >= MAX_OPEN_SESSIONS) {
|
|
61
|
+
throw new ToolRefusal('mcp.session_limit', `You already hold ${open.length} open sessions, the most one member may. Submit or discard one first: ${open.map((s) => s.name).join(', ')}.`, { sessions: open.map((s) => ({ session: s.name, root: s.root })) });
|
|
62
|
+
}
|
|
63
|
+
let started;
|
|
64
|
+
try {
|
|
65
|
+
started = await startSession(write, label);
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
// The core names the existing worktree's server path; over MCP the label is enough, and the member's own session is named by its root.
|
|
69
|
+
if (err instanceof ContextureError && err.finding.code === 'session.name_exists') {
|
|
70
|
+
const mine = open.find((s) => sessionLabelFromDirName(write.config, s.name) === err.finding.subject);
|
|
71
|
+
throw new ToolRefusal('session.name_exists', mine === undefined
|
|
72
|
+
? `A session labelled "${err.finding.subject}" already exists; start this one under another label.`
|
|
73
|
+
: `You already have a session labelled "${err.finding.subject}": ${mine.name}, root ${mine.root}. Work there, or start this one under another label.`, mine === undefined ? {} : { session: mine.name, root: mine.root });
|
|
74
|
+
}
|
|
75
|
+
throw err;
|
|
76
|
+
}
|
|
77
|
+
await ownershipOf(write).record(started.name, { owner: email, kind: 'session', started_at: write.now().toISOString() });
|
|
78
|
+
const root = await sessionRootFor(write, started.name);
|
|
79
|
+
return {
|
|
80
|
+
session: started.name,
|
|
81
|
+
root,
|
|
82
|
+
branch: started.branch,
|
|
83
|
+
label: started.label,
|
|
84
|
+
message: `Started session ${started.name}. Address its files under ${root} (for example ${root}<path>); nothing is published until session_submit.`,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
// ---- session_list ---------------------------------------------------------------
|
|
88
|
+
export const SESSION_LIST_INPUT_SCHEMA = { type: 'object', properties: {} };
|
|
89
|
+
export async function sessionListTool(write, email) {
|
|
90
|
+
const mine = new Map((await memberSessions(write, email)).map((s) => [s.name, s]));
|
|
91
|
+
const listed = await listSessions(write.git, write.canonicalRoot, write.config, {
|
|
92
|
+
review: { forge: write.forge, recordingLogin: write.config.change_approval?.recording_login ?? null },
|
|
93
|
+
});
|
|
94
|
+
const rows = [];
|
|
95
|
+
for (const entry of listed.sessions) {
|
|
96
|
+
const session = mine.get(entry.name);
|
|
97
|
+
if (session === undefined)
|
|
98
|
+
continue;
|
|
99
|
+
rows.push({
|
|
100
|
+
session: entry.name,
|
|
101
|
+
root: session.root,
|
|
102
|
+
branch: entry.branch,
|
|
103
|
+
label: sessionLabelFromDirName(write.config, entry.name),
|
|
104
|
+
kind: session.kind,
|
|
105
|
+
started_at: session.started_at,
|
|
106
|
+
uncommitted: entry.uncommitted,
|
|
107
|
+
ahead: entry.ahead,
|
|
108
|
+
pull_request: entry.pull_request ?? null,
|
|
109
|
+
review: entry.review ?? null,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
return { sessions: rows, forge_reachable: listed.forge_reachable !== false, limit: MAX_OPEN_SESSIONS };
|
|
113
|
+
}
|
|
114
|
+
// ---- session_status -------------------------------------------------------------
|
|
115
|
+
export const SESSION_STATUS_INPUT_SCHEMA = {
|
|
116
|
+
type: 'object',
|
|
117
|
+
properties: {
|
|
118
|
+
session: SESSION_PROPERTY,
|
|
119
|
+
diff: { type: 'boolean', description: `Also return the unified diff of uncommitted work, up to ${STATUS_DIFF_MAX_BYTES / 1024} KB.` },
|
|
120
|
+
},
|
|
121
|
+
required: ['session'],
|
|
122
|
+
};
|
|
123
|
+
/** A path relative to the worktree's top level, as the tools address it: under the session root. */
|
|
124
|
+
async function shownPath(write, session, topRelative) {
|
|
125
|
+
const prefix = await repoPrefixOf(write);
|
|
126
|
+
return `${session.root}${topRelative.startsWith(prefix) ? topRelative.slice(prefix.length) : topRelative}`;
|
|
127
|
+
}
|
|
128
|
+
export async function sessionStatusTool(write, email, args) {
|
|
129
|
+
const session = await ownedSession(write, email, args.session);
|
|
130
|
+
const status = await sessionStatus({ git: write.git, config: write.config, env: write.env, credentials: write.credentials }, session.ref, { diff: optionalBoolean(args, 'diff') });
|
|
131
|
+
let diff = status.diff;
|
|
132
|
+
let truncated = false;
|
|
133
|
+
if (diff !== null && Buffer.byteLength(diff, 'utf8') > STATUS_DIFF_MAX_BYTES) {
|
|
134
|
+
diff = Buffer.from(diff, 'utf8').subarray(0, STATUS_DIFF_MAX_BYTES).toString('utf8');
|
|
135
|
+
truncated = true;
|
|
136
|
+
}
|
|
137
|
+
const { worktree: _worktree, ...rest } = status;
|
|
138
|
+
return {
|
|
139
|
+
...rest,
|
|
140
|
+
root: session.root,
|
|
141
|
+
uncommitted: await Promise.all(status.uncommitted.map(async (c) => ({ status: c.status, path: await shownPath(write, session, c.path) }))),
|
|
142
|
+
diff,
|
|
143
|
+
diff_truncated: truncated,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
// ---- session_submit -------------------------------------------------------------
|
|
147
|
+
export const SESSION_SUBMIT_INPUT_SCHEMA = {
|
|
148
|
+
type: 'object',
|
|
149
|
+
properties: {
|
|
150
|
+
session: SESSION_PROPERTY,
|
|
151
|
+
branch: { type: 'string', description: 'The branch name the pull request carries, e.g. "notes/kestrel-intro"; the session\'s branch is renamed to it.' },
|
|
152
|
+
message: { type: 'string', description: 'The commit message: a subject line, a blank line, then what changed and why.' },
|
|
153
|
+
title: { type: 'string', description: 'The pull request title.' },
|
|
154
|
+
body: { type: 'string', description: 'The pull request body: why, what changed, route, verification and follow-ups. The Pages and Knowledge changes sections are appended for you; leave them out.' },
|
|
155
|
+
},
|
|
156
|
+
required: ['session', 'branch', 'message', 'title', 'body'],
|
|
157
|
+
};
|
|
158
|
+
/** Under the write mutex. */
|
|
159
|
+
export async function sessionSubmitTool(write, email, args) {
|
|
160
|
+
const input = { branch: requiredString(args, 'branch'), message: requiredString(args, 'message'), title: requiredString(args, 'title'), body: requiredString(args, 'body') };
|
|
161
|
+
const session = await ownedSession(write, email, args.session);
|
|
162
|
+
if (await rebaseInProgress(write.git, session.ref.path)) {
|
|
163
|
+
throw new ToolRefusal('mcp.rebase_in_progress', `A rebase is in progress in ${session.name}, so it cannot be submitted. Resolve the conflicts with Edit and call session_rebase with continue: true, or undo the rebase with abort: true.`, { session: session.name });
|
|
164
|
+
}
|
|
165
|
+
const submitted = await submitSession({ ...write, commit: memberCommit(write, email, 'Edited-by') }, session.ref, input);
|
|
166
|
+
const approval = write.config.change_approval === undefined ? null : approvalUrl(write, session.name);
|
|
167
|
+
const { worktree: _worktree, ...rest } = submitted;
|
|
168
|
+
return {
|
|
169
|
+
...rest,
|
|
170
|
+
root: session.root,
|
|
171
|
+
approval_url: approval,
|
|
172
|
+
message: `Submitted ${session.name} as pull request #${submitted.pull_request.number} (${submitted.steps.pull_request}).` +
|
|
173
|
+
(approval === null ? '' : ` It lands once someone approves it at ${approval}; share that address with whoever decides.`),
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
// ---- session_rebase -------------------------------------------------------------
|
|
177
|
+
export const SESSION_REBASE_INPUT_SCHEMA = {
|
|
178
|
+
type: 'object',
|
|
179
|
+
properties: {
|
|
180
|
+
session: SESSION_PROPERTY,
|
|
181
|
+
continue: { type: 'boolean', description: 'Stage the resolved files and continue the rebase in progress.' },
|
|
182
|
+
abort: { type: 'boolean', description: 'Abort the rebase in progress and restore the session as it was.' },
|
|
183
|
+
},
|
|
184
|
+
required: ['session'],
|
|
185
|
+
};
|
|
186
|
+
/** Under the write mutex. A conflict is a result, not a refusal: the conflicting files are returned with both sides. */
|
|
187
|
+
export async function sessionRebaseTool(write, email, args) {
|
|
188
|
+
const doContinue = optionalBoolean(args, 'continue');
|
|
189
|
+
const doAbort = optionalBoolean(args, 'abort');
|
|
190
|
+
if (doContinue && doAbort)
|
|
191
|
+
throw invalid('Pass continue or abort, not both.');
|
|
192
|
+
const session = await ownedSession(write, email, args.session);
|
|
193
|
+
const mode = doContinue ? 'continue' : doAbort ? 'abort' : 'start';
|
|
194
|
+
const result = await rebaseSession({ git: write.git, config: write.config, env: write.env, credentials: write.credentials }, session.ref, mode);
|
|
195
|
+
const conflicts = await Promise.all(result.conflicts.map(async (c) => ({ ...c, path: await shownPath(write, session, c.path) })));
|
|
196
|
+
const message = result.outcome === 'conflict'
|
|
197
|
+
? `The rebase stopped on ${conflicts.length} conflicting file(s): ${conflicts.map((c) => c.path).join(', ')}. Edit each to keep both sides' meaning, removing the conflict markers, then call session_rebase with continue: true.`
|
|
198
|
+
: result.outcome === 'aborted'
|
|
199
|
+
? `The rebase was aborted; ${session.name} is as it was.`
|
|
200
|
+
: result.outcome === 'up-to-date'
|
|
201
|
+
? `${session.name} is already on ${result.onto}.`
|
|
202
|
+
: `${session.name} is rebased onto ${result.onto}. Submitting it again pushes the rewritten branch with a lease.`;
|
|
203
|
+
return { ...result, root: session.root, conflicts, message };
|
|
204
|
+
}
|
|
205
|
+
// ---- session_discard ------------------------------------------------------------
|
|
206
|
+
export const SESSION_DISCARD_INPUT_SCHEMA = {
|
|
207
|
+
type: 'object',
|
|
208
|
+
properties: {
|
|
209
|
+
session: SESSION_PROPERTY,
|
|
210
|
+
force: { type: 'boolean', description: 'Discard uncommitted changes and commits the remote branch lacks. Without it, a session holding unpublished work is refused.' },
|
|
211
|
+
close_pull_request: { type: 'boolean', description: "Also close the session's open pull request." },
|
|
212
|
+
},
|
|
213
|
+
required: ['session'],
|
|
214
|
+
};
|
|
215
|
+
/** Under the write mutex. Destructive. */
|
|
216
|
+
export async function sessionDiscardTool(write, email, args) {
|
|
217
|
+
const force = optionalBoolean(args, 'force');
|
|
218
|
+
const closePullRequest = optionalBoolean(args, 'close_pull_request');
|
|
219
|
+
const session = await ownedSession(write, email, args.session);
|
|
220
|
+
const result = await discardSession({ git: write.git, config: write.config, credentials: write.credentials, forge: write.forge, env: write.env }, session.ref, { force, closePullRequest });
|
|
221
|
+
await ownershipOf(write).forget(session.name);
|
|
222
|
+
const { worktree: _worktree, ...rest } = result;
|
|
223
|
+
const closed = result.closed_pull_request === null ? '' : ` Pull request #${result.closed_pull_request} is closed.`;
|
|
224
|
+
return { ...rest, message: `Discarded ${session.name} and its branch ${result.branch}.${closed}` };
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../../../src/core/mcp/tools/sessions.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/core/notes/list.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/core/notes/list.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAK1D,+DAA+D;AAC/D,MAAM,WAAW,SAAS;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,IAAI;IACnB,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACjD,IAAI,EAAE,MAAM,CAAC;CACd;AAmCD;;;;;GAKG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CAuBjE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAEpF;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAEjF;AA8CD;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAM1F;AAED,wGAAwG;AACxG,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,GAAE,SAAc,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAQ9G"}
|
package/dist/core/notes/list.js
CHANGED
|
@@ -3,6 +3,7 @@ import { readdir } from 'node:fs/promises';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { configuredAdapters } from '../../adapters/registry.js';
|
|
5
5
|
import { isUnderAnyPrefix } from '../fs/prefix.js';
|
|
6
|
+
import { declaresSharedStores, SHARED_STORES_DIR } from '../shared-stores-location.js';
|
|
6
7
|
import { parseNote } from './parse.js';
|
|
7
8
|
/** Infrastructure directories intrinsic to contexture itself — never configurable content locations. */
|
|
8
9
|
const ALWAYS_SKIP_DIRS = new Set(['.git', '.githooks', '.queue']);
|
|
@@ -58,6 +59,10 @@ export function excludedPrefixesFor(config) {
|
|
|
58
59
|
config.templates.path,
|
|
59
60
|
// standardize-store-operating-guidance: the store log records what happened, never a note.
|
|
60
61
|
config.organize.log_path ?? DEFAULT_LOG_PATH,
|
|
62
|
+
// mount-shared-stores (D7): mounted stores are their own stores, never this
|
|
63
|
+
// one's notes. Only when mounts are declared, so a store with an ordinary
|
|
64
|
+
// `shared/` folder of its own is unchanged.
|
|
65
|
+
...(declaresSharedStores(config) ? [SHARED_STORES_DIR] : []),
|
|
61
66
|
];
|
|
62
67
|
}
|
|
63
68
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/core/notes/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAcvC,wGAAwG;AACxG,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;AAElE;;;;;;;;;GASG;AACH,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;AAEjD;;;;;GAKG;AACH,SAAS,iBAAiB,CAAC,MAAmB;IAC5C,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CACZ,kBAAkB,CAAC,MAAM,EAAE,oBAAoB,CAAC;aAC7C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;aAC3B,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC,CACxD,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,GAAG,EAAE,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,MAAM,UAAU,mBAAmB,CAAC,MAAmB;IACrD,OAAO;QACL,GAAG,MAAM,CAAC,SAAS,CAAC,aAAa;QACjC,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK;QACvB,MAAM,CAAC,OAAO,CAAC,cAAc;QAC7B,MAAM,CAAC,OAAO,CAAC,IAAI;QACnB,yFAAyF;QACzF,MAAM,CAAC,OAAO,CAAC,IAAI;QACnB,sFAAsF;QACtF,MAAM,CAAC,OAAO,CAAC,WAAW;QAC1B,MAAM,CAAC,OAAO,CAAC,aAAa;QAC5B,yEAAyE;QACzE,2EAA2E;QAC3E,yEAAyE;QACzE,gEAAgE;QAChE,MAAM,CAAC,SAAS,CAAC,IAAI;QACrB,2FAA2F;QAC3F,MAAM,CAAC,QAAQ,CAAC,QAAQ,IAAI,gBAAgB;
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/core/notes/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACvF,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAcvC,wGAAwG;AACxG,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;AAElE;;;;;;;;;GASG;AACH,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;AAEjD;;;;;GAKG;AACH,SAAS,iBAAiB,CAAC,MAAmB;IAC5C,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CACZ,kBAAkB,CAAC,MAAM,EAAE,oBAAoB,CAAC;aAC7C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;aAC3B,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC,CACxD,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,GAAG,EAAE,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,MAAM,UAAU,mBAAmB,CAAC,MAAmB;IACrD,OAAO;QACL,GAAG,MAAM,CAAC,SAAS,CAAC,aAAa;QACjC,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK;QACvB,MAAM,CAAC,OAAO,CAAC,cAAc;QAC7B,MAAM,CAAC,OAAO,CAAC,IAAI;QACnB,yFAAyF;QACzF,MAAM,CAAC,OAAO,CAAC,IAAI;QACnB,sFAAsF;QACtF,MAAM,CAAC,OAAO,CAAC,WAAW;QAC1B,MAAM,CAAC,OAAO,CAAC,aAAa;QAC5B,yEAAyE;QACzE,2EAA2E;QAC3E,yEAAyE;QACzE,gEAAgE;QAChE,MAAM,CAAC,SAAS,CAAC,IAAI;QACrB,2FAA2F;QAC3F,MAAM,CAAC,QAAQ,CAAC,QAAQ,IAAI,gBAAgB;QAC5C,4EAA4E;QAC5E,0EAA0E;QAC1E,4CAA4C;QAC5C,GAAG,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7D,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,MAAmB;IAC/C,OAAO,aAAa,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;AAC/E,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,cAAc,CAAC,YAAoB,EAAE,MAAmB;IACtE,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,aAAa,CACpB,eAAkC,EAClC,aAAkC;IAElC,OAAO,CAAC,YAAY,EAAE,EAAE;QACtB,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;QAC5C,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACxC,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QACzF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QACpG,OAAO,CAAC,gBAAgB,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;IAC1D,CAAC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,IAAI,CACjB,GAAW,EACX,IAAY,EACZ,eAAkC,EAClC,MAAyC,EACzC,OAAiB;IAEjB,IAAI,OAAO,CAAC;IACZ,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO;QAC7D,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE7E,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,mFAAmF;YACnF,IAAI,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,SAAS;YAC/C,IAAI,gBAAgB,CAAC,YAAY,EAAE,eAAe,CAAC;gBAAE,SAAS;YAC9D,MAAM,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/D,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;YAClD,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,SAAiB,EAAE,MAAmB;IACvE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACrE,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,MAAM,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,EAAE,EAAE,aAAa,CAAC,EAAE,EAAE,IAAI,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;IACpF,aAAa,CAAC,IAAI,EAAE,CAAC;IACrB,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;AACvH,CAAC;AAED,wGAAwG;AACxG,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,SAAiB,EAAE,MAAmB,EAAE,KAAK,GAAc,EAAE;IAC3F,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,MAAM,eAAe,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,CAAC,eAAe,EAAE,iBAAiB,CAAC,MAAM,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;IAC5H,aAAa,CAAC,IAAI,EAAE,CAAC;IAErB,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,WAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;IAC1H,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;AAChH,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { StoreConfig } from '../../config/schema.js';
|
|
2
|
+
import { ContextureError } from '../errors.js';
|
|
3
|
+
import type { GitRunner } from '../git/exec.js';
|
|
4
|
+
/**
|
|
5
|
+
* serve-the-session-lifecycle-to-chat-apps D7 (harness-portability spec,
|
|
6
|
+
* *`ctxr plugin build` writes the store's chat-app plugins*): the one builder
|
|
7
|
+
* behind both `ctxr plugin build` and serve's `/plugin/` downloads. It does no
|
|
8
|
+
* I/O of its own beyond reading the packaged templates, so the command writes
|
|
9
|
+
* what it returns to disk and the server answers with it from memory.
|
|
10
|
+
*
|
|
11
|
+
* Each plugin is the MCP render of the owned skills plus one remote MCP server
|
|
12
|
+
* entry at `serve.base_url` + `/mcp`, in that vendor's manifest format. Neither
|
|
13
|
+
* carries a credential (sign-in is the server's own OAuth with dynamic client
|
|
14
|
+
* registration), a variable in the address, a hook, a local server or a
|
|
15
|
+
* top-level `bin/` directory: the trees below are the whole of what is written.
|
|
16
|
+
*/
|
|
17
|
+
export declare const PLUGIN_TARGETS: readonly ['claude', 'chatgpt'];
|
|
18
|
+
export type PluginTarget = (typeof PLUGIN_TARGETS)[number];
|
|
19
|
+
/** Both vendors cap a plugin's and a skill's name at 64 characters, and a skill's description at 1,024. */
|
|
20
|
+
export declare const MAX_NAME_LENGTH = 64;
|
|
21
|
+
export declare const MAX_DESCRIPTION_LENGTH = 1024;
|
|
22
|
+
export interface PluginBuildInput {
|
|
23
|
+
config: StoreConfig;
|
|
24
|
+
/** The store's name, which the plugin's name and display name derive from. */
|
|
25
|
+
storeName: string;
|
|
26
|
+
cliVersion: string;
|
|
27
|
+
/** The commit the plugin is rendered from; null in a repository with no commit yet. */
|
|
28
|
+
commit: string | null;
|
|
29
|
+
}
|
|
30
|
+
export interface BuiltPlugin {
|
|
31
|
+
target: PluginTarget;
|
|
32
|
+
/** Every file of the plugin directory, by posix path relative to it. */
|
|
33
|
+
files: ReadonlyMap<string, string>;
|
|
34
|
+
/** `<name>-<target>.zip`. */
|
|
35
|
+
archiveName: string;
|
|
36
|
+
/** The same files, as one ZIP archive with the manifest at its root. */
|
|
37
|
+
archive: Buffer;
|
|
38
|
+
}
|
|
39
|
+
export interface PluginBundle {
|
|
40
|
+
storeName: string;
|
|
41
|
+
name: string;
|
|
42
|
+
displayName: string;
|
|
43
|
+
version: string;
|
|
44
|
+
mcpUrl: string;
|
|
45
|
+
/** The skill directories both plugins carry. */
|
|
46
|
+
skills: string[];
|
|
47
|
+
plugins: BuiltPlugin[];
|
|
48
|
+
}
|
|
49
|
+
/** The configuration error a store without the MCP surface gets: there is no server for a plugin to name. */
|
|
50
|
+
export declare class PluginWithoutMcpError extends ContextureError {
|
|
51
|
+
constructor();
|
|
52
|
+
}
|
|
53
|
+
type Escape = (value: string) => string;
|
|
54
|
+
/** One pass, so a substituted value that happens to contain a token is never substituted again. */
|
|
55
|
+
export declare function fillPluginTemplate(file: string, values: Readonly<Record<string, string>>, escape?: Escape): string;
|
|
56
|
+
/** `contexture-<store name slug>`, within the 64-character limit both vendors set. */
|
|
57
|
+
export declare function pluginName(storeName: string): string;
|
|
58
|
+
/** The CLI version, with the rendered commit as semver build metadata. */
|
|
59
|
+
export declare function pluginVersion(cliVersion: string, commit: string | null): string;
|
|
60
|
+
export declare function buildPlugins(input: PluginBuildInput): PluginBundle;
|
|
61
|
+
/**
|
|
62
|
+
* The store's name: its directory in the canonical clone, so a build run from
|
|
63
|
+
* a session worktree names the store, not the worktree. A store below the
|
|
64
|
+
* repository's root is named for its own directory.
|
|
65
|
+
*/
|
|
66
|
+
export declare function storeNameFor(git: GitRunner, root: string): Promise<string>;
|
|
67
|
+
/** The commit a plugin renders from: the checkout's HEAD, or null before the first commit. */
|
|
68
|
+
export declare function renderedCommit(git: GitRunner, root: string): Promise<string | null>;
|
|
69
|
+
export {};
|
|
70
|
+
//# sourceMappingURL=build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/core/plugin/build.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAG1D,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAIhD;;;;;;;;;;;;GAYG;AAEH,eAAO,MAAM,cAAc,YAAI,QAAQ,EAAE,SAAS,CAAU,CAAC;AAC7D,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D,2GAA2G;AAC3G,eAAO,MAAM,eAAe,KAAK,CAAC;AAClC,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAG3C,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,WAAW,CAAC;IACpB,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,uFAAuF;IACvF,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,YAAY,CAAC;IACrB,wEAAwE;IACxE,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,6BAA6B;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,gDAAgD;IAChD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,6GAA6G;AAC7G,qBAAa,qBAAsB,SAAQ,eAAe;IACxD,cAMC;CACF;AAiBD,KAAK,MAAM,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;AAIxC,mGAAmG;AACnG,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,GAAE,MAA2F,GAAG,MAAM,CAMtM;AAOD,sFAAsF;AACtF,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAMpD;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAE/E;AAYD,wBAAgB,YAAY,CAAC,KAAK,EAAE,gBAAgB,GAAG,YAAY,CAmDlE;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMhF;AAED,8FAA8F;AAC9F,wBAAsB,cAAc,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGzF"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { escapeHtml } from '../browse/render.js';
|
|
5
|
+
import { SKILL_FILE_NAME } from '../conventions.js';
|
|
6
|
+
import { ContextureError } from '../errors.js';
|
|
7
|
+
import { ExitCode } from '../exit-codes.js';
|
|
8
|
+
import { renderSkills } from '../skills.js';
|
|
9
|
+
import { createZip } from './zip.js';
|
|
10
|
+
/**
|
|
11
|
+
* serve-the-session-lifecycle-to-chat-apps D7 (harness-portability spec,
|
|
12
|
+
* *`ctxr plugin build` writes the store's chat-app plugins*): the one builder
|
|
13
|
+
* behind both `ctxr plugin build` and serve's `/plugin/` downloads. It does no
|
|
14
|
+
* I/O of its own beyond reading the packaged templates, so the command writes
|
|
15
|
+
* what it returns to disk and the server answers with it from memory.
|
|
16
|
+
*
|
|
17
|
+
* Each plugin is the MCP render of the owned skills plus one remote MCP server
|
|
18
|
+
* entry at `serve.base_url` + `/mcp`, in that vendor's manifest format. Neither
|
|
19
|
+
* carries a credential (sign-in is the server's own OAuth with dynamic client
|
|
20
|
+
* registration), a variable in the address, a hook, a local server or a
|
|
21
|
+
* top-level `bin/` directory: the trees below are the whole of what is written.
|
|
22
|
+
*/
|
|
23
|
+
export const PLUGIN_TARGETS = ['claude', 'chatgpt'];
|
|
24
|
+
/** Both vendors cap a plugin's and a skill's name at 64 characters, and a skill's description at 1,024. */
|
|
25
|
+
export const MAX_NAME_LENGTH = 64;
|
|
26
|
+
export const MAX_DESCRIPTION_LENGTH = 1024;
|
|
27
|
+
const NAME_PREFIX = 'contexture-';
|
|
28
|
+
/** The configuration error a store without the MCP surface gets: there is no server for a plugin to name. */
|
|
29
|
+
export class PluginWithoutMcpError extends ContextureError {
|
|
30
|
+
constructor() {
|
|
31
|
+
super(ExitCode.Usage, {
|
|
32
|
+
code: 'plugin.mcp_not_declared',
|
|
33
|
+
severity: 'error',
|
|
34
|
+
message: 'This store declares no mcp block in contexture.yaml, so there is no MCP server for a chat-app plugin to connect to. Declare mcp (which needs change_approval and serve.base_url) first.',
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const templateCache = new Map();
|
|
39
|
+
/**
|
|
40
|
+
* `templates/plugin/<file>`. Read whole, not through `packagedTemplate()`:
|
|
41
|
+
* these are JSON and HTML documents, not markdown fragments.
|
|
42
|
+
*/
|
|
43
|
+
function pluginTemplate(file) {
|
|
44
|
+
let text = templateCache.get(file);
|
|
45
|
+
if (text === undefined) {
|
|
46
|
+
text = readFileSync(fileURLToPath(new URL(`../../../templates/plugin/${file}`, import.meta.url)), 'utf8');
|
|
47
|
+
templateCache.set(file, text);
|
|
48
|
+
}
|
|
49
|
+
return text;
|
|
50
|
+
}
|
|
51
|
+
const asJsonString = (value) => JSON.stringify(value).slice(1, -1);
|
|
52
|
+
const asIs = (value) => value;
|
|
53
|
+
/** One pass, so a substituted value that happens to contain a token is never substituted again. */
|
|
54
|
+
export function fillPluginTemplate(file, values, escape = file.endsWith('.json') ? asJsonString : file.endsWith('.html') ? escapeHtml : asIs) {
|
|
55
|
+
return pluginTemplate(file).replace(/__[A-Z][A-Z0-9_]*__/g, (token) => {
|
|
56
|
+
const value = values[token.slice(2, -2)];
|
|
57
|
+
if (value === undefined)
|
|
58
|
+
throw new Error(`templates/plugin/${file} carries an unknown placeholder ${token}`);
|
|
59
|
+
return escape(value);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/** A JSON template, filled and parsed, so a template that stops being JSON fails the build rather than shipping. */
|
|
63
|
+
function jsonDocument(file, values) {
|
|
64
|
+
return `${JSON.stringify(JSON.parse(fillPluginTemplate(file, values)), null, 2)}\n`;
|
|
65
|
+
}
|
|
66
|
+
/** `contexture-<store name slug>`, within the 64-character limit both vendors set. */
|
|
67
|
+
export function pluginName(storeName) {
|
|
68
|
+
const slug = storeName
|
|
69
|
+
.toLowerCase()
|
|
70
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
71
|
+
.replace(/^-+|-+$/g, '');
|
|
72
|
+
return `${NAME_PREFIX}${slug === '' ? 'store' : slug}`.slice(0, MAX_NAME_LENGTH).replace(/-+$/, '');
|
|
73
|
+
}
|
|
74
|
+
/** The CLI version, with the rendered commit as semver build metadata. */
|
|
75
|
+
export function pluginVersion(cliVersion, commit) {
|
|
76
|
+
return commit === null ? cliVersion : `${cliVersion}+${commit.slice(0, 12)}`;
|
|
77
|
+
}
|
|
78
|
+
/** Reads a rendered SKILL.md's frontmatter and holds it to the Agent Skills limits both vendors apply. */
|
|
79
|
+
function checkSkillFrontmatter(folder, content) {
|
|
80
|
+
const match = /^---\nname: (.*)\ndescription: (.*)\n---\n/.exec(content);
|
|
81
|
+
if (match === null)
|
|
82
|
+
throw new Error(`skill ${folder} renders no name and description frontmatter`);
|
|
83
|
+
const [, name, description] = match;
|
|
84
|
+
if (name !== folder)
|
|
85
|
+
throw new Error(`skill ${folder} is named "${name}" in its frontmatter`);
|
|
86
|
+
if (name.length > MAX_NAME_LENGTH || !/^[a-z0-9]+(-[a-z0-9]+)*$/.test(name))
|
|
87
|
+
throw new Error(`skill name "${name}" is not a lowercase name of at most ${MAX_NAME_LENGTH} characters`);
|
|
88
|
+
if (description.length === 0 || description.length > MAX_DESCRIPTION_LENGTH)
|
|
89
|
+
throw new Error(`skill ${folder}'s description is not 1 to ${MAX_DESCRIPTION_LENGTH} characters`);
|
|
90
|
+
}
|
|
91
|
+
export function buildPlugins(input) {
|
|
92
|
+
const { config } = input;
|
|
93
|
+
const baseUrl = config.serve?.base_url;
|
|
94
|
+
if (config.mcp === undefined || baseUrl === undefined)
|
|
95
|
+
throw new PluginWithoutMcpError();
|
|
96
|
+
const origin = baseUrl.replace(/\/+$/, '');
|
|
97
|
+
const mcpUrl = `${origin}/mcp`;
|
|
98
|
+
const name = pluginName(input.storeName);
|
|
99
|
+
const version = pluginVersion(input.cliVersion, input.commit);
|
|
100
|
+
const displayName = `${input.storeName} (contexture)`;
|
|
101
|
+
const values = { NAME: name, DISPLAY_NAME: displayName, VERSION: version, STORE_NAME: input.storeName, MCP_URL: mcpUrl, BASE_URL: origin };
|
|
102
|
+
const skills = renderSkills(config, 'mcp');
|
|
103
|
+
const skillFiles = new Map();
|
|
104
|
+
for (const skill of skills) {
|
|
105
|
+
checkSkillFrontmatter(skill.file, skill.content);
|
|
106
|
+
skillFiles.set(`skills/${skill.file}/${SKILL_FILE_NAME}`, skill.content);
|
|
107
|
+
for (const [rel, content] of skill.supportingFiles)
|
|
108
|
+
skillFiles.set(`skills/${skill.file}/${rel}`, content);
|
|
109
|
+
}
|
|
110
|
+
const readme = fillPluginTemplate('README.md', values);
|
|
111
|
+
const trees = {
|
|
112
|
+
claude: new Map([
|
|
113
|
+
['.claude-plugin/plugin.json', jsonDocument('claude-plugin.json', values)],
|
|
114
|
+
['.mcp.json', jsonDocument('claude-mcp.json', values)],
|
|
115
|
+
['README.md', readme],
|
|
116
|
+
...skillFiles,
|
|
117
|
+
]),
|
|
118
|
+
chatgpt: new Map([
|
|
119
|
+
['plugin.json', jsonDocument('chatgpt-plugin.json', values)],
|
|
120
|
+
['mcp.json', jsonDocument('chatgpt-mcp.json', values)],
|
|
121
|
+
['README.md', readme],
|
|
122
|
+
...skillFiles,
|
|
123
|
+
]),
|
|
124
|
+
};
|
|
125
|
+
const plugins = PLUGIN_TARGETS.map((target) => {
|
|
126
|
+
const files = trees[target];
|
|
127
|
+
for (const file of files.keys()) {
|
|
128
|
+
// A Claude plugin with a top-level bin/ is refused at upload, and neither app runs a hook from a plugin we ship.
|
|
129
|
+
if (file === 'bin' || file.startsWith('bin/') || file.startsWith('hooks/'))
|
|
130
|
+
throw new Error(`plugin file ${file} is one neither app may be shipped`);
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
target,
|
|
134
|
+
files,
|
|
135
|
+
archiveName: `${name}-${target}.zip`,
|
|
136
|
+
archive: createZip([...files].map(([file, content]) => ({ path: file, data: Buffer.from(content, 'utf8') }))),
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
return { storeName: input.storeName, name, displayName, version, mcpUrl, skills: skills.map((skill) => skill.file), plugins };
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* The store's name: its directory in the canonical clone, so a build run from
|
|
143
|
+
* a session worktree names the store, not the worktree. A store below the
|
|
144
|
+
* repository's root is named for its own directory.
|
|
145
|
+
*/
|
|
146
|
+
export async function storeNameFor(git, root) {
|
|
147
|
+
const prefix = (await git.run(['rev-parse', '--show-prefix'], { cwd: root, allowFailure: true })).stdout.trim().replace(/\/+$/, '');
|
|
148
|
+
if (prefix !== '')
|
|
149
|
+
return path.posix.basename(prefix);
|
|
150
|
+
const common = await git.run(['rev-parse', '--path-format=absolute', '--git-common-dir'], { cwd: root, allowFailure: true });
|
|
151
|
+
const dir = common.exitCode === 0 ? common.stdout.trim() : '';
|
|
152
|
+
return dir === '' ? path.basename(root) : path.basename(path.dirname(dir));
|
|
153
|
+
}
|
|
154
|
+
/** The commit a plugin renders from: the checkout's HEAD, or null before the first commit. */
|
|
155
|
+
export async function renderedCommit(git, root) {
|
|
156
|
+
const head = await git.run(['rev-parse', '--verify', '--quiet', 'HEAD^{commit}'], { cwd: root, allowFailure: true });
|
|
157
|
+
return head.exitCode === 0 && head.stdout.trim() !== '' ? head.stdout.trim() : null;
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../../src/core/plugin/build.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { IncomingMessage } from 'node:http';
|
|
2
|
+
import type { ApprovalServer } from '../browse/approve.js';
|
|
3
|
+
import type { GitRunner } from '../git/exec.js';
|
|
4
|
+
import type { Store } from '../store.js';
|
|
5
|
+
/**
|
|
6
|
+
* serve-the-session-lifecycle-to-chat-apps D7 (remote-access spec, *Members
|
|
7
|
+
* download the store's plugins from the server*): `GET /plugin/` names the two
|
|
8
|
+
* downloads and how to install each, and `GET /plugin/<name>-<app>.zip` is that
|
|
9
|
+
* archive, built in memory by the builder `ctxr plugin build` uses, from the
|
|
10
|
+
* configuration the server last loaded.
|
|
11
|
+
*
|
|
12
|
+
* The routes exist only while the MCP surface is configured, and every one
|
|
13
|
+
* needs the verified identity assertion the approval routes need, so they are
|
|
14
|
+
* not among the paths an access proxy lets through without a login. A
|
|
15
|
+
* verified person the `mcp` block does not admit is refused as sign-in
|
|
16
|
+
* refuses them: the plugin would connect them to nothing.
|
|
17
|
+
*/
|
|
18
|
+
export declare const PLUGIN_ROUTE = "/plugin/";
|
|
19
|
+
export declare function isPluginPath(pathname: string): boolean;
|
|
20
|
+
export interface PluginReply {
|
|
21
|
+
status: number;
|
|
22
|
+
contentType: string;
|
|
23
|
+
body: string | Buffer;
|
|
24
|
+
headers?: Record<string, string>;
|
|
25
|
+
}
|
|
26
|
+
export declare class PluginDownloads {
|
|
27
|
+
private readonly git;
|
|
28
|
+
/** The last bundle built, keyed by the commit and the configuration it was built from. */
|
|
29
|
+
private cached;
|
|
30
|
+
private storeName;
|
|
31
|
+
constructor(git: GitRunner);
|
|
32
|
+
private bundleFor;
|
|
33
|
+
handle(store: Store, approval: ApprovalServer | null, approvalError: string | null, req: IncomingMessage, pathname: string): Promise<PluginReply>;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/core/plugin/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAIzC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,YAAY,aAAa,CAAC;AAEvC,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAID,qBAAa,eAAe;IAKd,OAAO,CAAC,QAAQ,CAAC,GAAG;IAJhC,0FAA0F;IAC1F,OAAO,CAAC,MAAM,CAAsD;IACpE,OAAO,CAAC,SAAS,CAA8B;IAE/C,YAA6B,GAAG,EAAE,SAAS,EAAI;YAEjC,SAAS;IAUjB,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAgCtJ;CACF"}
|