dsh-pstack 0.2.0-beta.1 → 0.2.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/LICENSE +2 -3
- package/README.md +148 -84
- package/README.zh.md +198 -0
- package/assets/pstack-config-entry.png +0 -0
- package/cordis.patch.yml +105 -27
- package/dist/client.mjs +2341 -0
- package/dist/client.mjs.map +1 -0
- package/dist/host-contract-CUPSpeNk.d.mts +22 -0
- package/dist/index.d.mts +49 -238
- package/dist/index.mjs +250 -123
- package/dist/models.d.mts +44 -0
- package/dist/models.mjs +201 -0
- package/dist/paths-BT77khwm.mjs +48 -0
- package/dist/pstack/LICENSE +21 -0
- package/dist/pstack/README.md +291 -0
- package/dist/pstack/agents/poteto-agent.md +9 -0
- package/{assets → dist/pstack}/docs/guide/01-setup.md +13 -11
- package/{assets → dist/pstack}/docs/guide/02-poteto-mode.md +4 -4
- package/{assets → dist/pstack}/docs/guide/04-design.md +4 -4
- package/{assets → dist/pstack}/docs/guide/05-build-and-clean.md +2 -2
- package/{assets → dist/pstack}/docs/guide/06-verify-and-ship.md +13 -3
- package/{assets → dist/pstack}/docs/guide/07-overnight.md +15 -13
- package/{assets → dist/pstack}/docs/guide/09-make-it-yours.md +6 -2
- package/{assets → dist/pstack}/docs/guide/10-recipes-and-pitfalls.md +7 -5
- package/{assets → dist/pstack}/docs/guide/README.md +1 -1
- package/dist/pstack/docs/harness/dsh.md +98 -0
- package/{assets → dist/pstack}/skills/architect/SKILL.md +12 -12
- package/dist/pstack/skills/arena/SKILL.md +50 -0
- package/{assets → dist/pstack}/skills/automate-me/SKILL.md +14 -14
- package/{assets → dist/pstack}/skills/benchmark-checklist/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/blast-radius/SKILL.md +4 -6
- package/{assets → dist/pstack}/skills/correct/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/create-formal-verification-skill/SKILL.md +4 -2
- package/{assets → dist/pstack}/skills/create-verification-skill/SKILL.md +5 -5
- package/dist/pstack/skills/figure-it-out/SKILL.md +54 -0
- package/dist/pstack/skills/how/SKILL.md +38 -0
- package/{assets → dist/pstack}/skills/in-your-own-words/SKILL.md +1 -1
- package/dist/pstack/skills/interrogate/SKILL.md +33 -0
- package/{assets → dist/pstack}/skills/ketchup/SKILL.md +3 -5
- package/dist/pstack/skills/ketchup-video/SKILL.md +29 -0
- package/{assets → dist/pstack}/skills/maintain-formal-verification-skill/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/maintain-verification-skill/SKILL.md +3 -3
- package/dist/pstack/skills/make-bot-ui/SKILL.md +117 -0
- package/dist/pstack/skills/no-comments/SKILL.md +26 -0
- package/{assets → dist/pstack}/skills/poteto-help/SKILL.md +34 -31
- package/{assets → dist/pstack}/skills/poteto-help/references/prompting.md +1 -1
- package/{assets → dist/pstack}/skills/poteto-help/references/recipes.md +3 -3
- package/{assets → dist/pstack}/skills/poteto-mode/SKILL.md +20 -19
- package/dist/pstack/skills/poteto-mode/playbooks/authoring-a-skill.md +12 -0
- package/dist/pstack/skills/poteto-mode/playbooks/autonomous-run.md +13 -0
- package/dist/pstack/skills/poteto-mode/playbooks/autopilot-full.md +25 -0
- package/dist/pstack/skills/poteto-mode/playbooks/autopilot-stack.md +8 -0
- package/{assets → dist/pstack}/skills/poteto-mode/playbooks/babysit.md +4 -4
- package/dist/pstack/skills/poteto-mode/playbooks/bug-fix.md +15 -0
- package/{assets → dist/pstack}/skills/poteto-mode/playbooks/eval.md +3 -3
- package/dist/pstack/skills/poteto-mode/playbooks/feature.md +21 -0
- package/{assets → dist/pstack}/skills/poteto-mode/playbooks/hillclimb.md +3 -3
- package/{assets → dist/pstack}/skills/poteto-mode/playbooks/investigation.md +2 -2
- package/{assets → dist/pstack}/skills/poteto-mode/playbooks/multi-phase-plan.md +23 -23
- package/{assets → dist/pstack}/skills/poteto-mode/playbooks/opening-a-pr.md +6 -6
- package/dist/pstack/skills/poteto-mode/playbooks/orchestrate.md +25 -0
- package/{assets → dist/pstack}/skills/poteto-mode/playbooks/pause-safely.md +2 -2
- package/dist/pstack/skills/poteto-mode/playbooks/perf-issue.md +25 -0
- package/{assets → dist/pstack}/skills/poteto-mode/playbooks/prototype.md +4 -4
- package/dist/pstack/skills/poteto-mode/playbooks/refactoring.md +16 -0
- package/dist/pstack/skills/poteto-mode/playbooks/runtime-forensics.md +11 -0
- package/dist/pstack/skills/poteto-mode/playbooks/session-pickup.md +11 -0
- package/{assets → dist/pstack}/skills/poteto-mode/playbooks/shipping.md +2 -2
- package/{assets → dist/pstack}/skills/poteto-mode/playbooks/trace-forensics.md +2 -2
- package/dist/pstack/skills/poteto-mode/playbooks/visual-parity.md +11 -0
- package/dist/pstack/skills/poteto-mode/playbooks/worktree-cleanup.md +12 -0
- package/{assets → dist/pstack}/skills/poteto-mode/scripts/check-plan.mjs +6 -8
- package/dist/pstack/skills/poteto-mode/scripts/check-plan.test.mjs +128 -0
- package/{assets/skills/poteto-mode/scripts/check-plan.test.mjs → dist/pstack/skills/poteto-mode/scripts/expect.mjs} +12 -101
- package/dist/pstack/skills/poteto-mode/scripts/support.mjs +93 -0
- package/dist/pstack/skills/poteto-mode/scripts/watch-pr/cli.mjs +123 -0
- package/dist/pstack/skills/poteto-mode/scripts/watch-pr/cli.test.mjs +217 -0
- package/dist/pstack/skills/poteto-mode/scripts/watch-pr/fakes.test-helper.mjs +119 -0
- package/dist/pstack/skills/poteto-mode/scripts/watch-pr/github.mjs +626 -0
- package/dist/pstack/skills/poteto-mode/scripts/watch-pr/github.test.mjs +521 -0
- package/dist/pstack/skills/poteto-mode/scripts/watch-pr/policy.mjs +657 -0
- package/dist/pstack/skills/poteto-mode/scripts/watch-pr/policy.test.mjs +523 -0
- package/dist/pstack/skills/poteto-mode/scripts/watch-pr/render.mjs +106 -0
- package/dist/pstack/skills/poteto-mode/scripts/watch-pr/types.mjs +9 -0
- package/dist/pstack/skills/poteto-mode/scripts/watch-pr/watch-pr.mjs +5 -0
- package/{assets → dist/pstack}/skills/poteto-mode/scripts/worktree-audit.mjs +15 -22
- package/dist/pstack/skills/poteto-mode/scripts/worktree-audit.test.mjs +134 -0
- package/{assets → dist/pstack}/skills/principle-attack-the-premise/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/principle-boundary-discipline/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/principle-encode-lessons-in-structure/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/principle-exhaust-the-design-space/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/principle-experience-first/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/principle-explain-the-number/SKILL.md +3 -2
- package/{assets → dist/pstack}/skills/principle-fix-root-causes/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/principle-laziness-protocol/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/principle-make-operations-idempotent/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/principle-minimize-reader-load/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/principle-model-the-domain/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/principle-never-block-on-the-human/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/principle-outcome-oriented-execution/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/principle-prove-it-works/SKILL.md +2 -2
- package/{assets → dist/pstack}/skills/principle-redesign-from-first-principles/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/principle-separate-before-serializing-shared-state/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/principle-sequence-verifiable-units/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/principle-subtract-before-you-add/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/principle-test-behavior-not-implementation/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/principle-type-system-discipline/SKILL.md +1 -1
- package/dist/pstack/skills/recall/SKILL.md +37 -0
- package/dist/pstack/skills/reflect/SKILL.md +71 -0
- package/{assets → dist/pstack}/skills/reflect/references/divergent-reviewer.md +4 -4
- package/{assets → dist/pstack}/skills/reflect/references/judgment-reviewer.md +2 -2
- package/{assets → dist/pstack}/skills/reflect/references/synthesizer.md +5 -5
- package/{assets → dist/pstack}/skills/reflect/references/tooling-reviewer.md +2 -2
- package/dist/pstack/skills/setup-pstack/SKILL.md +80 -0
- package/{assets → dist/pstack}/skills/sharpen/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/show-me-your-work/SKILL.md +8 -8
- package/{assets → dist/pstack}/skills/show-me-your-work/scripts/log.mjs +1 -3
- package/dist/pstack/skills/show-me-your-work/scripts/log.test.mjs +56 -0
- package/dist/pstack/skills/statechart/SKILL.md +82 -0
- package/dist/pstack/skills/statechart/references/render.md +93 -0
- package/dist/pstack/skills/statechart/scripts/backends/cfg.mjs +31 -0
- package/dist/pstack/skills/statechart/scripts/backends/mermaid.mjs +186 -0
- package/dist/pstack/skills/statechart/scripts/backends/plain-text.mjs +62 -0
- package/dist/pstack/skills/statechart/scripts/backends/report.mjs +84 -0
- package/dist/pstack/skills/statechart/scripts/frontends/config.mjs +268 -0
- package/dist/pstack/skills/statechart/scripts/frontends/dot.mjs +67 -0
- package/dist/pstack/skills/statechart/scripts/frontends/marks.mjs +94 -0
- package/dist/pstack/skills/statechart/scripts/frontends/messages.mjs +48 -0
- package/dist/pstack/skills/statechart/scripts/frontends/spec.mjs +101 -0
- package/dist/pstack/skills/statechart/scripts/frontends/trace.mjs +39 -0
- package/dist/pstack/skills/statechart/scripts/frontends/value.mjs +180 -0
- package/dist/pstack/skills/statechart/scripts/frontends/verdict.mjs +40 -0
- package/dist/pstack/skills/statechart/scripts/frontends/view.mjs +99 -0
- package/dist/pstack/skills/statechart/scripts/ir.mjs +277 -0
- package/dist/pstack/skills/statechart/scripts/passes/annotate.mjs +92 -0
- package/dist/pstack/skills/statechart/scripts/passes/label.mjs +210 -0
- package/dist/pstack/skills/statechart/scripts/passes/lift.mjs +84 -0
- package/dist/pstack/skills/statechart/scripts/passes/loop-check.mjs +47 -0
- package/dist/pstack/skills/statechart/scripts/passes/paths.mjs +72 -0
- package/dist/pstack/skills/statechart/scripts/passes/reach.mjs +135 -0
- package/dist/pstack/skills/statechart/scripts/passes/region-check.mjs +82 -0
- package/dist/pstack/skills/statechart/scripts/passes/regions.mjs +268 -0
- package/dist/pstack/skills/statechart/scripts/pipeline.mjs +72 -0
- package/dist/pstack/skills/statechart/scripts/run.mjs +440 -0
- package/dist/pstack/skills/statechart/scripts/statechart.mjs +155 -0
- package/dist/pstack/skills/statechart/scripts/statechart.test.mjs +198 -0
- package/dist/pstack/skills/statechart/scripts/worker.mjs +31 -0
- package/dist/pstack/skills/swarm/SKILL.md +43 -0
- package/{assets → dist/pstack}/skills/tdd/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/teach/SKILL.md +2 -2
- package/{assets → dist/pstack}/skills/technical-writing/SKILL.md +1 -1
- package/{assets → dist/pstack}/skills/typescript-best-practices/SKILL.md +3 -6
- package/{assets → dist/pstack}/skills/why/SKILL.md +8 -8
- package/dist/remote.d.mts +27 -0
- package/dist/remote.mjs +234 -0
- package/dist/role-config-NNn5r1JX.mjs +415 -0
- package/dist/role-manifest-C3fUzjLI.d.mts +19 -0
- package/dist/role-wire-DZwTn2wF.d.mts +55 -0
- package/dist/roles.d.mts +18 -0
- package/dist/roles.mjs +323 -0
- package/dist/script.d.mts +9 -111
- package/dist/script.mjs +32 -329
- package/dist/skill.d.mts +38 -0
- package/dist/skill.mjs +183 -0
- package/dist/skills/authored/decision-audit/SKILL.md +103 -0
- package/dist/skills/authored/decision-audit/SKILL.zh.md +103 -0
- package/dist/skills/authored/decision-audit/references/recover-commit.md +17 -0
- package/dist/skills/authored/decision-audit/references/recover-commit.zh.md +17 -0
- package/dist/skills/authored/decision-write/SKILL.md +133 -0
- package/dist/skills/authored/decision-write/SKILL.zh.md +133 -0
- package/dist/skills/authored/decision-write/references/land.md +48 -0
- package/dist/skills/authored/decision-write/references/land.zh.md +48 -0
- package/dist/skills/authored/decision-write/references/scope.md +16 -0
- package/dist/skills/authored/decision-write/references/scope.zh.md +16 -0
- package/dist/skills/authored/docs-drift/SKILL.md +120 -0
- package/dist/skills/authored/docs-drift/SKILL.zh.md +120 -0
- package/dist/skills/authored/setup-project-docs/SKILL.md +63 -0
- package/dist/skills/authored/setup-project-docs/SKILL.zh.md +63 -0
- package/dist/skills/authored/setup-project-docs/references/decision-conventions.md +13 -0
- package/dist/skills/authored/setup-project-docs/references/decision-conventions.zh.md +13 -0
- package/dist/skills/vendored/retro/SKILL.md +44 -0
- package/dist/skills/vendored/retro/agents/openai.yaml +5 -0
- package/dist/skills/vendored/writing-for-agents/SKILL-MECHANICS.md +22 -0
- package/dist/skills/vendored/writing-for-agents/SKILL.md +81 -0
- package/dist/skills/vendored/writing-for-agents/agents/openai.yaml +3 -0
- package/dist/subagent.d.mts +54 -206
- package/dist/subagent.mjs +258 -963
- package/locale/en.json +3 -2
- package/locale/zh.json +3 -2
- package/package.json +93 -66
- package/assets/agents/poteto-agent.md +0 -8
- package/assets/docs/harness/dsh.md +0 -60
- package/assets/docs/pstack-models.example.md +0 -54
- package/assets/skills/arena/SKILL.md +0 -50
- package/assets/skills/figure-it-out/SKILL.md +0 -54
- package/assets/skills/how/SKILL.md +0 -38
- package/assets/skills/interrogate/SKILL.md +0 -71
- package/assets/skills/interrogate/references/code-quality-review.md +0 -47
- package/assets/skills/interrogate/references/lead-judgment.md +0 -39
- package/assets/skills/interrogate/references/reviewer-prompt.md +0 -62
- package/assets/skills/interrogate/references/rubric.md +0 -77
- package/assets/skills/no-comments/SKILL.md +0 -26
- package/assets/skills/poteto-mode/playbooks/authoring-a-skill.md +0 -12
- package/assets/skills/poteto-mode/playbooks/autonomous-run.md +0 -15
- package/assets/skills/poteto-mode/playbooks/autopilot-full.md +0 -25
- package/assets/skills/poteto-mode/playbooks/autopilot-stack.md +0 -12
- package/assets/skills/poteto-mode/playbooks/bug-fix.md +0 -15
- package/assets/skills/poteto-mode/playbooks/feature.md +0 -21
- package/assets/skills/poteto-mode/playbooks/orchestrate.md +0 -112
- package/assets/skills/poteto-mode/playbooks/perf-issue.md +0 -25
- package/assets/skills/poteto-mode/playbooks/refactoring.md +0 -16
- package/assets/skills/poteto-mode/playbooks/runtime-forensics.md +0 -11
- package/assets/skills/poteto-mode/playbooks/session-pickup.md +0 -11
- package/assets/skills/poteto-mode/playbooks/visual-parity.md +0 -11
- package/assets/skills/poteto-mode/playbooks/worktree-cleanup.md +0 -20
- package/assets/skills/poteto-mode/scripts/orch/orch.mjs +0 -4282
- package/assets/skills/poteto-mode/scripts/orch/orch.test.mjs +0 -2042
- package/assets/skills/poteto-mode/scripts/watch-pr/cli.test.mjs +0 -5101
- package/assets/skills/poteto-mode/scripts/watch-pr/github.test.mjs +0 -1177
- package/assets/skills/poteto-mode/scripts/watch-pr/policy.test.mjs +0 -1441
- package/assets/skills/poteto-mode/scripts/watch-pr/watch-pr.mjs +0 -4601
- package/assets/skills/recall/SKILL.md +0 -37
- package/assets/skills/reflect/SKILL.md +0 -69
- package/assets/skills/setup-pstack/SKILL.md +0 -67
- package/assets/skills/swarm/SKILL.md +0 -43
- package/dist/frontmatter-BQX3ekwP.mjs +0 -229
- package/dist/frontmatter-BQX3ekwP.mjs.map +0 -1
- package/dist/history.d.mts +0 -429
- package/dist/history.mjs +0 -1129
- package/dist/history.mjs.map +0 -1
- package/dist/host-contract-o47JH_r8.d.mts +0 -527
- package/dist/index.mjs.map +0 -1
- package/dist/paths-D_JlVmBk.mjs +0 -42
- package/dist/paths-D_JlVmBk.mjs.map +0 -1
- package/dist/script.mjs.map +0 -1
- package/dist/subagent.mjs.map +0 -1
- /package/{static/icon.png → assets/logo.png} +0 -0
- /package/{assets → dist/pstack}/agents/comment-sicko.md +0 -0
- /package/{assets → dist/pstack}/docs/guide/03-understand.md +0 -0
- /package/{assets → dist/pstack}/docs/guide/08-principles.md +0 -0
- /package/{assets → dist/pstack}/docs/guide/images/design.jpg +0 -0
- /package/{assets → dist/pstack}/docs/guide/images/overnight.jpg +0 -0
- /package/{assets → dist/pstack}/docs/guide/images/recipes.jpg +0 -0
- /package/{assets → dist/pstack}/docs/guide/images/router.jpg +0 -0
- /package/{assets → dist/pstack}/docs/guide/images/understanding.jpg +0 -0
- /package/{assets → dist/pstack}/docs/guide/images/verification.jpg +0 -0
- /package/{assets → dist/pstack}/skills/architect/references/design-red-flags.md +0 -0
- /package/{assets → dist/pstack}/skills/architect/references/rationale-template.md +0 -0
- /package/{assets → dist/pstack}/skills/architect/references/runner-prompt.md +0 -0
- /package/{assets → dist/pstack}/skills/bro/SKILL.md +0 -0
- /package/{assets → dist/pstack}/skills/create-verification-skill/references/feature-map-example/README.md +0 -0
- /package/{assets → dist/pstack}/skills/create-verification-skill/references/feature-map-example/create-note.md +0 -0
- /package/{assets → dist/pstack}/skills/create-verification-skill/references/feature-map-example/search.md +0 -0
- /package/{assets → dist/pstack}/skills/how/references/explainer-prompt.md +0 -0
- /package/{assets → dist/pstack}/skills/how/references/explorer-prompt.md +0 -0
- /package/{assets → dist/pstack}/skills/poteto-mode/references/bugbot-triage.md +0 -0
- /package/{assets → dist/pstack}/skills/principle-build-the-lever/SKILL.md +0 -0
- /package/{assets → dist/pstack}/skills/principle-foundational-thinking/SKILL.md +0 -0
- /package/{assets → dist/pstack}/skills/principle-guard-the-context-window/SKILL.md +0 -0
- /package/{assets → dist/pstack}/skills/show-me-your-work/references/decision-log-template.tsv +0 -0
- /package/{assets → dist/pstack}/skills/typescript-best-practices/references/patterns.md +0 -0
- /package/{assets → dist/pstack}/skills/unslop/SKILL.md +0 -0
- /package/{assets → dist/pstack}/skills/why/references/epistemics.md +0 -0
- /package/{assets → dist/pstack}/skills/why/references/investigator-prompt.md +0 -0
- /package/{assets → dist/pstack}/skills/why/references/source-playbook.md +0 -0
- /package/{assets → dist/pstack}/skills/why/references/sources/code-archaeology.md +0 -0
- /package/{assets → dist/pstack}/skills/why/references/sources/databricks.md +0 -0
- /package/{assets → dist/pstack}/skills/why/references/sources/datadog.md +0 -0
- /package/{assets → dist/pstack}/skills/why/references/sources/incident-postmortem.md +0 -0
- /package/{assets → dist/pstack}/skills/why/references/sources/linear.md +0 -0
- /package/{assets → dist/pstack}/skills/why/references/sources/notion.md +0 -0
- /package/{assets → dist/pstack}/skills/why/references/sources/sentry.md +0 -0
- /package/{assets → dist/pstack}/skills/why/references/sources/slack.md +0 -0
- /package/{assets → dist/pstack}/skills/why/references/synthesizer-prompt.md +0 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import "./models.mjs";
|
|
2
|
+
import { n as RoleValueShape } from "./role-manifest-C3fUzjLI.mjs";
|
|
3
|
+
/** Which spelling of "inherit the parent route" a role line uses. */
|
|
4
|
+
type InheritAlias = "inherit-parent" | "auto";
|
|
5
|
+
/** One role value as the configuration page sees it. */
|
|
6
|
+
type RouteView = {
|
|
7
|
+
readonly kind: "inherit";
|
|
8
|
+
readonly alias: InheritAlias;
|
|
9
|
+
} | {
|
|
10
|
+
readonly kind: "route";
|
|
11
|
+
readonly provider: string;
|
|
12
|
+
readonly model: string;
|
|
13
|
+
readonly effort?: string;
|
|
14
|
+
};
|
|
15
|
+
/** One of the 17 roles in manifest order. */
|
|
16
|
+
interface RoleView {
|
|
17
|
+
readonly key: string;
|
|
18
|
+
readonly shape: RoleValueShape;
|
|
19
|
+
/** Whether the role file configures this role. */
|
|
20
|
+
readonly configured: boolean;
|
|
21
|
+
/** The winning line, when the role file configures this role. */
|
|
22
|
+
readonly line?: number;
|
|
23
|
+
readonly routes: readonly RouteView[];
|
|
24
|
+
readonly issues: readonly string[];
|
|
25
|
+
}
|
|
26
|
+
/** One file-level problem. Unknown and malformed lines are reported, never dropped. */
|
|
27
|
+
interface RoleFileIssue {
|
|
28
|
+
readonly line?: number;
|
|
29
|
+
readonly message: string;
|
|
30
|
+
}
|
|
31
|
+
/** Everything the configuration page renders about `$DSH_HOME/pstack-models.mdc`. */
|
|
32
|
+
interface RoleFileSnapshot {
|
|
33
|
+
readonly path: string;
|
|
34
|
+
readonly status: "missing" | "loaded" | "unreadable";
|
|
35
|
+
readonly reason?: string;
|
|
36
|
+
readonly budget?: string;
|
|
37
|
+
readonly roles: readonly RoleView[];
|
|
38
|
+
readonly issues: readonly RoleFileIssue[];
|
|
39
|
+
/** False only when the file cannot be read at all. */
|
|
40
|
+
readonly canSave: boolean;
|
|
41
|
+
}
|
|
42
|
+
/** One role save. List roles carry every route, never only the edited one. */
|
|
43
|
+
interface SaveRoleRequest {
|
|
44
|
+
readonly key: string;
|
|
45
|
+
readonly routes: readonly RouteView[];
|
|
46
|
+
}
|
|
47
|
+
/** A refused save leaves the file untouched and names the reason. */
|
|
48
|
+
type SaveRoleResult = {
|
|
49
|
+
readonly ok: true;
|
|
50
|
+
readonly snapshot: RoleFileSnapshot;
|
|
51
|
+
} | {
|
|
52
|
+
readonly ok: false;
|
|
53
|
+
readonly reason: string;
|
|
54
|
+
};
|
|
55
|
+
export { SaveRoleRequest as n, SaveRoleResult as r, RoleFileSnapshot as t };
|
package/dist/roles.d.mts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CatalogueResult } from "./models.mjs";
|
|
2
|
+
import { n as SaveRoleRequest, r as SaveRoleResult, t as RoleFileSnapshot } from "./role-wire-DZwTn2wF.mjs";
|
|
3
|
+
import { Context, Service } from "@deepseek-ai/cordis";
|
|
4
|
+
import { TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
|
|
5
|
+
/** Read and write the role file for the Plugins configuration page. */
|
|
6
|
+
export declare class PstackRolesService extends TypertRemoteService {
|
|
7
|
+
static inject: string[];
|
|
8
|
+
constructor(ctx: Context);
|
|
9
|
+
protected [Service.init](): void;
|
|
10
|
+
/** Current path, status, values, and per-line issues. */
|
|
11
|
+
status(): RoleFileSnapshot;
|
|
12
|
+
/** The live directory the page offers for its provider/model/effort selects. */
|
|
13
|
+
catalogue(signal: AbortSignal): Promise<CatalogueResult>;
|
|
14
|
+
/** Validate and save one role, then return the reloaded snapshot. */
|
|
15
|
+
save(request: SaveRoleRequest, signal: AbortSignal): Promise<SaveRoleResult>;
|
|
16
|
+
private get llm();
|
|
17
|
+
}
|
|
18
|
+
export { PstackRolesService as default };
|
package/dist/roles.mjs
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import { collectCatalogue } from "./models.mjs";
|
|
2
|
+
import { REMOTE_PACKAGE, ROLES_SERVICE, pstackRolesRemote } from "./remote.mjs";
|
|
3
|
+
import { a as resolveDshHome, c as ROLE_MANIFEST, l as findRoleSpec, n as normalizeRoleName, r as readRoleConfiguration, s as INHERIT_PARENT_ALIASES, t as modelsFilePath } from "./role-config-NNn5r1JX.mjs";
|
|
4
|
+
import { dirname } from "node:path";
|
|
5
|
+
import { mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { Service } from "@deepseek-ai/cordis";
|
|
7
|
+
import { TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
|
|
8
|
+
import { randomUUID } from "node:crypto";
|
|
9
|
+
// src/internal/role-editor.ts
|
|
10
|
+
/**
|
|
11
|
+
* Role-file editing behind the Plugins configuration page.
|
|
12
|
+
*
|
|
13
|
+
* The writer changes exactly one role line and leaves every other byte of the
|
|
14
|
+
* file alone: unknown lines, malformed lines, comments, and `# budget` survive a
|
|
15
|
+
* save. Saves are validated against the live `pstack_models` catalogue before
|
|
16
|
+
* the first byte is written, so a rejected save leaves the file unchanged.
|
|
17
|
+
*/
|
|
18
|
+
function routeView(route) {
|
|
19
|
+
if (route.kind === "inherit") return {
|
|
20
|
+
kind: "inherit",
|
|
21
|
+
alias: route.alias ?? "inherit-parent"
|
|
22
|
+
};
|
|
23
|
+
return {
|
|
24
|
+
kind: "route",
|
|
25
|
+
provider: route.provider,
|
|
26
|
+
model: route.model,
|
|
27
|
+
...route.effort === void 0 ? {} : { effort: route.effort }
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function roleView(spec, entry) {
|
|
31
|
+
return {
|
|
32
|
+
key: spec.key,
|
|
33
|
+
shape: spec.shape,
|
|
34
|
+
configured: entry !== void 0,
|
|
35
|
+
...entry === void 0 ? {} : { line: entry.line },
|
|
36
|
+
routes: entry === void 0 ? [] : entry.routes.map(routeView),
|
|
37
|
+
issues: entry === void 0 ? [] : [...entry.issues]
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/** Project a parsed file onto the manifest, preserving order and per-line issues. */
|
|
41
|
+
function snapshotFromConfiguration(config) {
|
|
42
|
+
if (config.status === "unreadable") return {
|
|
43
|
+
path: config.path,
|
|
44
|
+
status: "unreadable",
|
|
45
|
+
reason: config.reason,
|
|
46
|
+
roles: ROLE_MANIFEST.map((spec) => roleView(spec, void 0)),
|
|
47
|
+
issues: [],
|
|
48
|
+
canSave: false
|
|
49
|
+
};
|
|
50
|
+
if (config.status === "missing") return {
|
|
51
|
+
path: config.path,
|
|
52
|
+
status: "missing",
|
|
53
|
+
roles: ROLE_MANIFEST.map((spec) => roleView(spec, void 0)),
|
|
54
|
+
issues: [],
|
|
55
|
+
canSave: true
|
|
56
|
+
};
|
|
57
|
+
return {
|
|
58
|
+
path: config.path,
|
|
59
|
+
status: "loaded",
|
|
60
|
+
...config.budget === void 0 ? {} : { budget: config.budget },
|
|
61
|
+
roles: ROLE_MANIFEST.map((spec) => roleView(spec, config.roles.get(spec.key))),
|
|
62
|
+
issues: config.issues.map((issue) => ({
|
|
63
|
+
...issue.line === void 0 ? {} : { line: issue.line },
|
|
64
|
+
message: issue.message
|
|
65
|
+
})),
|
|
66
|
+
canSave: true
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/** Validate one save against the manifest and the live catalogue. */
|
|
70
|
+
function validateSaveRequest(request, catalogue) {
|
|
71
|
+
if (typeof request !== "object" || request === null || Array.isArray(request)) return {
|
|
72
|
+
ok: false,
|
|
73
|
+
reason: "the save request must be an object"
|
|
74
|
+
};
|
|
75
|
+
if (typeof request.key !== "string") return {
|
|
76
|
+
ok: false,
|
|
77
|
+
reason: "the save request must name a role"
|
|
78
|
+
};
|
|
79
|
+
const spec = findRoleSpec(normalizeRoleName(request.key));
|
|
80
|
+
if (spec === void 0) return {
|
|
81
|
+
ok: false,
|
|
82
|
+
reason: `unknown role ${JSON.stringify(request.key)}`
|
|
83
|
+
};
|
|
84
|
+
if (!Array.isArray(request.routes)) return {
|
|
85
|
+
ok: false,
|
|
86
|
+
reason: `role "${spec.key}" must carry a route list`
|
|
87
|
+
};
|
|
88
|
+
if (spec.shape === "single" && request.routes.length !== 1) return {
|
|
89
|
+
ok: false,
|
|
90
|
+
reason: `role "${spec.key}" holds a single route; save exactly one`
|
|
91
|
+
};
|
|
92
|
+
if (request.routes.length === 0) return {
|
|
93
|
+
ok: false,
|
|
94
|
+
reason: `role "${spec.key}" must keep at least one route`
|
|
95
|
+
};
|
|
96
|
+
const routes = [];
|
|
97
|
+
for (let index = 0; index < request.routes.length; index += 1) {
|
|
98
|
+
const route = request.routes[index];
|
|
99
|
+
const position = request.routes.length === 1 ? "the route" : `route ${index + 1}`;
|
|
100
|
+
if (typeof route !== "object" || route === null || Array.isArray(route)) return {
|
|
101
|
+
ok: false,
|
|
102
|
+
reason: `${position} must be an object`
|
|
103
|
+
};
|
|
104
|
+
if (route.kind === "inherit") {
|
|
105
|
+
const alias = route.alias ?? "inherit-parent";
|
|
106
|
+
if (!INHERIT_PARENT_ALIASES.includes(alias)) return {
|
|
107
|
+
ok: false,
|
|
108
|
+
reason: `${position} has unknown inheritance alias ${JSON.stringify(alias)}; use \`inherit-parent\` or \`auto\``
|
|
109
|
+
};
|
|
110
|
+
routes.push({
|
|
111
|
+
kind: "inherit",
|
|
112
|
+
alias
|
|
113
|
+
});
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
const unknownKind = route.kind;
|
|
117
|
+
if (unknownKind !== "route") return {
|
|
118
|
+
ok: false,
|
|
119
|
+
reason: `${position} has unknown kind ${JSON.stringify(unknownKind)}`
|
|
120
|
+
};
|
|
121
|
+
const provider = typeof route.provider === "string" ? route.provider.trim() : "";
|
|
122
|
+
const model = typeof route.model === "string" ? route.model.trim() : "";
|
|
123
|
+
if (provider === "" || model === "") return {
|
|
124
|
+
ok: false,
|
|
125
|
+
reason: `${position} needs both a provider and a model`
|
|
126
|
+
};
|
|
127
|
+
const providerEntry = catalogue.providers.find((candidate) => candidate.provider === provider);
|
|
128
|
+
if (providerEntry === void 0) return {
|
|
129
|
+
ok: false,
|
|
130
|
+
reason: `provider ${JSON.stringify(provider)} is not in the live model directory; run \`pstack_models\` and pick a registered provider`
|
|
131
|
+
};
|
|
132
|
+
if (providerEntry.error !== void 0) return {
|
|
133
|
+
ok: false,
|
|
134
|
+
reason: `provider ${JSON.stringify(provider)} could not be discovered: ${providerEntry.error}`
|
|
135
|
+
};
|
|
136
|
+
const modelEntry = providerEntry.models.find((candidate) => candidate.id === model);
|
|
137
|
+
if (modelEntry === void 0) return {
|
|
138
|
+
ok: false,
|
|
139
|
+
reason: `provider ${JSON.stringify(provider)} does not advertise model ${JSON.stringify(model)}`
|
|
140
|
+
};
|
|
141
|
+
if (modelEntry.error !== void 0) return {
|
|
142
|
+
ok: false,
|
|
143
|
+
reason: `model ${JSON.stringify(`${provider}/${model}`)} could not be resolved: ${modelEntry.error}`
|
|
144
|
+
};
|
|
145
|
+
const effort = typeof route.effort === "string" ? route.effort.trim() : route.effort;
|
|
146
|
+
if (effort !== void 0 && effort !== "") {
|
|
147
|
+
if (!modelEntry.efforts.includes(effort)) return {
|
|
148
|
+
ok: false,
|
|
149
|
+
reason: `model ${JSON.stringify(`${provider}/${model}`)} does not declare effort ${JSON.stringify(effort)}; declared efforts: ${modelEntry.efforts.length === 0 ? "none" : modelEntry.efforts.join(", ")}`
|
|
150
|
+
};
|
|
151
|
+
routes.push({
|
|
152
|
+
kind: "route",
|
|
153
|
+
provider,
|
|
154
|
+
model,
|
|
155
|
+
effort
|
|
156
|
+
});
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
if (effort === "") return {
|
|
160
|
+
ok: false,
|
|
161
|
+
reason: `${position} has an empty effort; drop the effort or pick one`
|
|
162
|
+
};
|
|
163
|
+
routes.push({
|
|
164
|
+
kind: "route",
|
|
165
|
+
provider,
|
|
166
|
+
model
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
ok: true,
|
|
171
|
+
value: {
|
|
172
|
+
spec,
|
|
173
|
+
routes
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
/** Render one role's routes in the role-file grammar. */
|
|
178
|
+
function renderRoleValue(routes) {
|
|
179
|
+
return routes.map((route) => route.kind === "inherit" ? route.alias ?? "inherit-parent" : route.effort === void 0 ? `${route.provider}/${route.model}` : `${route.provider}/${route.model} [${route.effort}]`).join(", ");
|
|
180
|
+
}
|
|
181
|
+
function bodyStart(lines) {
|
|
182
|
+
if (lines[0]?.trim() !== "---") return 0;
|
|
183
|
+
for (let index = 1; index < lines.length; index += 1) if (lines[index]?.trim() === "---") return index + 1;
|
|
184
|
+
return 0;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Replace the winning line for one role, or append one when absent.
|
|
188
|
+
*
|
|
189
|
+
* Every other line is returned verbatim. A role configured twice keeps its
|
|
190
|
+
* earlier line and replaces the last one, which is the line the parser treats
|
|
191
|
+
* as winning; the duplicate remains visible as a per-line issue.
|
|
192
|
+
*/
|
|
193
|
+
function updateRoleText(text, spec, value) {
|
|
194
|
+
const lines = text.split("\n");
|
|
195
|
+
const crlf = text.includes("\r\n");
|
|
196
|
+
if (lines.length > 0 && lines[lines.length - 1] === "") lines.pop();
|
|
197
|
+
let match = -1;
|
|
198
|
+
for (let index = bodyStart(lines); index < lines.length; index += 1) {
|
|
199
|
+
const line = lines[index];
|
|
200
|
+
const trimmed = line.endsWith("\r") ? line.slice(0, -1).trim() : line.trim();
|
|
201
|
+
if (trimmed === "" || trimmed.startsWith("#")) continue;
|
|
202
|
+
const separator = trimmed.indexOf(":");
|
|
203
|
+
if (separator === -1) continue;
|
|
204
|
+
if (normalizeRoleName(trimmed.slice(0, separator)) !== spec.key) continue;
|
|
205
|
+
match = index;
|
|
206
|
+
}
|
|
207
|
+
const rendered = `${spec.key}: ${value}`;
|
|
208
|
+
if (match >= 0) {
|
|
209
|
+
const original = lines[match];
|
|
210
|
+
const indent = /^\s*/.exec(original)?.[0] ?? "";
|
|
211
|
+
const ending = original.endsWith("\r") ? "\r" : "";
|
|
212
|
+
lines[match] = `${indent}${rendered}${ending}`;
|
|
213
|
+
} else lines.push(`${rendered}${crlf ? "\r" : ""}`);
|
|
214
|
+
return `${lines.join("\n")}\n`;
|
|
215
|
+
}
|
|
216
|
+
function writeAtomically(path, text) {
|
|
217
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
218
|
+
const temporary = `${path}.${process.pid}.${randomUUID()}.tmp`;
|
|
219
|
+
try {
|
|
220
|
+
writeFileSync(temporary, text, "utf8");
|
|
221
|
+
renameSync(temporary, path);
|
|
222
|
+
} catch (error) {
|
|
223
|
+
rmSync(temporary, { force: true });
|
|
224
|
+
throw error;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Save one role and return the reloaded snapshot.
|
|
229
|
+
*
|
|
230
|
+
* A missing file is created with just this role. An unreadable file is never
|
|
231
|
+
* overwritten. Every refusal leaves the existing bytes untouched.
|
|
232
|
+
*/
|
|
233
|
+
function saveRoleConfiguration(path, request, catalogue) {
|
|
234
|
+
const current = readRoleConfiguration(path);
|
|
235
|
+
if (current.status === "unreadable") return {
|
|
236
|
+
ok: false,
|
|
237
|
+
reason: `the role file is unreadable: ${current.reason}`
|
|
238
|
+
};
|
|
239
|
+
const validation = validateSaveRequest(request, catalogue);
|
|
240
|
+
if (!validation.ok) return validation;
|
|
241
|
+
let existing = "";
|
|
242
|
+
if (current.status === "loaded") try {
|
|
243
|
+
existing = readFileSync(path, "utf8");
|
|
244
|
+
} catch (error) {
|
|
245
|
+
return {
|
|
246
|
+
ok: false,
|
|
247
|
+
reason: `the role file could not be read: ${describeError(error)}`
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
const next = updateRoleText(existing, validation.value.spec, renderRoleValue(validation.value.routes));
|
|
251
|
+
try {
|
|
252
|
+
writeAtomically(path, next);
|
|
253
|
+
} catch (error) {
|
|
254
|
+
return {
|
|
255
|
+
ok: false,
|
|
256
|
+
reason: `the role file could not be written: ${describeError(error)}`
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
return {
|
|
260
|
+
ok: true,
|
|
261
|
+
snapshot: snapshotFromConfiguration(readRoleConfiguration(path))
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
function describeError(error) {
|
|
265
|
+
if (error instanceof Error) {
|
|
266
|
+
const code = error.code;
|
|
267
|
+
return typeof code === "string" ? `${error.message} (${code})` : error.message;
|
|
268
|
+
}
|
|
269
|
+
return String(error);
|
|
270
|
+
}
|
|
271
|
+
// src/roles.ts
|
|
272
|
+
/**
|
|
273
|
+
* `pstack-roles`: the Host half of the role model configuration page.
|
|
274
|
+
*
|
|
275
|
+
* It owns no cached policy: every read and write goes to
|
|
276
|
+
* `$DSH_HOME/pstack-models.mdc`, which `pstack_subagent` also re-reads on every
|
|
277
|
+
* delegation. Saving therefore takes effect on the next delegation without a
|
|
278
|
+
* restart, and an already running child keeps the route it started with.
|
|
279
|
+
*/
|
|
280
|
+
/** Read and write the role file for the Plugins configuration page. */
|
|
281
|
+
var PstackRolesService = class extends TypertRemoteService {
|
|
282
|
+
static inject = ["llm", "typert"];
|
|
283
|
+
constructor(ctx) {
|
|
284
|
+
super(ctx, ROLES_SERVICE);
|
|
285
|
+
}
|
|
286
|
+
[Service.init]() {
|
|
287
|
+
const typert = this.ctx.typert;
|
|
288
|
+
if (typert === void 0) throw new Error("pstack-roles requires the Typert registry service");
|
|
289
|
+
typert.register({
|
|
290
|
+
package: REMOTE_PACKAGE,
|
|
291
|
+
face: "host",
|
|
292
|
+
schemas: [],
|
|
293
|
+
model: {
|
|
294
|
+
services: [],
|
|
295
|
+
events: [],
|
|
296
|
+
objects: []
|
|
297
|
+
},
|
|
298
|
+
invocations: pstackRolesRemote.descriptors
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
/** Current path, status, values, and per-line issues. */
|
|
302
|
+
status() {
|
|
303
|
+
return snapshotFromConfiguration(readRoleConfiguration(roleFilePath()));
|
|
304
|
+
}
|
|
305
|
+
/** The live directory the page offers for its provider/model/effort selects. */
|
|
306
|
+
async catalogue(signal) {
|
|
307
|
+
return collectCatalogue(this.llm, void 0, signal);
|
|
308
|
+
}
|
|
309
|
+
/** Validate and save one role, then return the reloaded snapshot. */
|
|
310
|
+
async save(request, signal) {
|
|
311
|
+
signal.throwIfAborted();
|
|
312
|
+
const catalogue = await collectCatalogue(this.llm, void 0, signal);
|
|
313
|
+
signal.throwIfAborted();
|
|
314
|
+
return saveRoleConfiguration(roleFilePath(), request, catalogue);
|
|
315
|
+
}
|
|
316
|
+
get llm() {
|
|
317
|
+
return this.ctx.llm;
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
function roleFilePath() {
|
|
321
|
+
return modelsFilePath(resolveDshHome());
|
|
322
|
+
}
|
|
323
|
+
export { PstackRolesService, PstackRolesService as default };
|
package/dist/script.d.mts
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
//#region src/script.d.ts
|
|
1
|
+
import { _ as ToolsHost, a as JobsHost, c as SessionId, g as ToolDefinition, i as JobId, o as JsonSchemaNode, v as WorkingDirectoryHost } from "./host-contract-CUPSpeNk.mjs";
|
|
3
2
|
/** Model-facing tool name. */
|
|
4
3
|
export declare const TOOL_NAME = "pstack_script";
|
|
5
4
|
/** The shipped scripts this tool may run, in display order. */
|
|
6
5
|
export declare const SCRIPT_IDS: string[];
|
|
7
6
|
export type ScriptId = (typeof SCRIPT_IDS)[number];
|
|
8
|
-
/** Default wall-clock limit for a foreground run. */
|
|
9
7
|
export declare const DEFAULT_TIMEOUT_MS = 120000;
|
|
10
|
-
/** Bounds a caller may set for one foreground run. */
|
|
11
8
|
export declare const MAX_TIMEOUT_MS = 600000;
|
|
12
|
-
/** Default cap on captured bytes per stream. */
|
|
13
9
|
export declare const DEFAULT_OUTPUT_LIMIT_BYTES: number;
|
|
14
10
|
/** Raised for an argument problem, before anything is spawned. */
|
|
15
11
|
export declare class ScriptInputError extends Error {
|
|
@@ -19,7 +15,6 @@ export declare class ScriptInputError extends Error {
|
|
|
19
15
|
export declare class ScriptMissingError extends Error {
|
|
20
16
|
constructor(message: string);
|
|
21
17
|
}
|
|
22
|
-
/** One parsed call. */
|
|
23
18
|
export interface ScriptArgs {
|
|
24
19
|
readonly id: ScriptId;
|
|
25
20
|
readonly args: readonly string[];
|
|
@@ -28,7 +23,6 @@ export interface ScriptArgs {
|
|
|
28
23
|
readonly timeoutMs?: number;
|
|
29
24
|
readonly outputLimitBytes?: number;
|
|
30
25
|
}
|
|
31
|
-
/** What a foreground run produced. */
|
|
32
26
|
export interface ScriptResult {
|
|
33
27
|
readonly kind: "foreground";
|
|
34
28
|
readonly id: ScriptId;
|
|
@@ -37,74 +31,35 @@ export interface ScriptResult {
|
|
|
37
31
|
readonly timedOut: boolean;
|
|
38
32
|
readonly stdout: string;
|
|
39
33
|
readonly stderr: string;
|
|
40
|
-
/** True when a stream was cut off at the limit. */
|
|
41
34
|
readonly stdoutTruncated: boolean;
|
|
42
35
|
readonly stderrTruncated: boolean;
|
|
43
36
|
readonly durationMs: number;
|
|
44
37
|
}
|
|
45
|
-
/** What a background run produced. */
|
|
46
38
|
export interface ScriptJobResult {
|
|
47
39
|
readonly kind: "background";
|
|
48
40
|
readonly id: ScriptId;
|
|
49
41
|
readonly jobId: JobId;
|
|
50
42
|
readonly status: string;
|
|
51
43
|
}
|
|
52
|
-
/** Either outcome, as the model sees it. */
|
|
53
44
|
export type ScriptOutcome = ScriptResult | ScriptJobResult;
|
|
54
45
|
/** Absolute path of one shipped artefact. */
|
|
55
46
|
export declare function scriptPath(id: ScriptId): string;
|
|
56
|
-
/**
|
|
57
|
-
* The environment a child gets.
|
|
58
|
-
*
|
|
59
|
-
* The one rule is the Electron selector. Under Electron, `process.execPath` is the
|
|
60
|
-
* Desktop binary, which starts a browser window unless `ELECTRON_RUN_AS_NODE=1` tells
|
|
61
|
-
* it to behave as Node. Under plain Node the variable is inert — Node ignores it —
|
|
62
|
-
* so setting it unconditionally would also work; it is conditional here so the
|
|
63
|
-
* environment of a normal run stays exactly the caller's, and the one code path that
|
|
64
|
-
* needs it is visible.
|
|
65
|
-
*/
|
|
47
|
+
/** The environment a child gets: the Electron selector, and otherwise the caller's. */
|
|
66
48
|
export declare function scriptEnvironment(base?: NodeJS.ProcessEnv, versions?: {
|
|
67
49
|
readonly electron?: string;
|
|
68
50
|
}): NodeJS.ProcessEnv;
|
|
69
51
|
/** Validate the raw tool arguments. */
|
|
70
52
|
export declare function parseScriptArgs(raw: unknown): ScriptArgs;
|
|
71
|
-
/**
|
|
72
|
-
* Resolve the directory the child runs in.
|
|
73
|
-
*
|
|
74
|
-
* The tool's `cwd` argument is documented as resolving against "this session's
|
|
75
|
-
* directory", so `sessionCwd` — the value `ctx.workingDirectory.ensure()` returns —
|
|
76
|
-
* is the base, not the Host process's working directory.
|
|
77
|
-
*
|
|
78
|
-
* - omitted -> the session directory
|
|
79
|
-
* - relative -> joined onto the session directory
|
|
80
|
-
* - absolute -> used as-is
|
|
81
|
-
*
|
|
82
|
-
* With no Session (a call outside an Agent) there is no session directory to
|
|
83
|
-
* anchor to; the argument is then passed through and `resolve` normalises it
|
|
84
|
-
* against the Host process, which is the only directory that exists.
|
|
85
|
-
*/
|
|
53
|
+
/** Resolve the directory the child runs in, relative to the caller-established session directory. */
|
|
86
54
|
export declare function resolveWorkingDirectory(requested: string | undefined, sessionCwd: string | undefined): string | undefined;
|
|
87
|
-
/**
|
|
88
|
-
* Run one script in the foreground.
|
|
89
|
-
*
|
|
90
|
-
* A nonzero exit, a signal, a timeout, and truncated output are all returned rather
|
|
91
|
-
* than raised: the caller needs to see what the script said before it failed, and an
|
|
92
|
-
* exception would discard the captured output.
|
|
93
|
-
*/
|
|
55
|
+
/** Run one script in the foreground. A nonzero exit, signal, timeout, and truncation are returned, not thrown. */
|
|
94
56
|
export declare function runForeground(args: ScriptArgs, options?: {
|
|
95
57
|
readonly execPath?: string;
|
|
96
58
|
readonly environment?: NodeJS.ProcessEnv;
|
|
97
|
-
/** Already resolved by the caller; see `resolveWorkingDirectory`. */
|
|
98
59
|
readonly cwd?: string;
|
|
99
60
|
readonly signal?: AbortSignal;
|
|
100
61
|
}): Promise<ScriptResult>;
|
|
101
|
-
/**
|
|
102
|
-
* Start a script as a background job.
|
|
103
|
-
*
|
|
104
|
-
* `jobs` is required and passing nothing is a refusal with a reason. A job whose
|
|
105
|
-
* output nobody can read would be worse than a failed call: the model would report a
|
|
106
|
-
* task as started and no notice would ever arrive.
|
|
107
|
-
*/
|
|
62
|
+
/** Start a script as a background job. `jobs` absent is a refusal with a reason. */
|
|
108
63
|
export declare function runBackground(args: ScriptArgs, options: {
|
|
109
64
|
readonly jobs?: JobsHost | undefined;
|
|
110
65
|
readonly caller?: SessionId;
|
|
@@ -112,82 +67,25 @@ export declare function runBackground(args: ScriptArgs, options: {
|
|
|
112
67
|
readonly environment?: NodeJS.ProcessEnv;
|
|
113
68
|
readonly cwd?: string;
|
|
114
69
|
}): Promise<ScriptJobResult>;
|
|
115
|
-
/**
|
|
116
|
-
* Render one captured stream as a fenced block, byte for byte.
|
|
117
|
-
*
|
|
118
|
-
* `trimEnd` used to run here, which is wrong for two reasons:
|
|
119
|
-
*
|
|
120
|
-
* - A stream of only whitespace passed the `!== ""` test and then rendered as an
|
|
121
|
-
* empty-looking `stdout:` line, so a reader concluded the script printed nothing.
|
|
122
|
-
* - `check-plan`'s contract includes exact line counts and blank-line separators, so
|
|
123
|
-
* a trimmed block is a different document — and the model reads this text as the
|
|
124
|
-
* script's output.
|
|
125
|
-
*
|
|
126
|
-
* A fence keeps every byte visible, including trailing blank lines. The fence is
|
|
127
|
-
* lengthened past the longest backtick run in the content so it can never be closed
|
|
128
|
-
* early by the content itself. Nothing inside is escaped or reinterpreted.
|
|
129
|
-
*/
|
|
70
|
+
/** Render one captured stream as a fence that the content cannot close early. */
|
|
130
71
|
export declare function renderCapturedStream(text: string): readonly string[];
|
|
131
72
|
/** Render one outcome for the model. */
|
|
132
73
|
export declare function renderScriptOutcome(outcome: ScriptOutcome): string;
|
|
133
|
-
/** The model-facing JSON Schema for `parameters`. */
|
|
134
74
|
export declare function buildScriptParameters(): Record<string, unknown>;
|
|
135
|
-
/**
|
|
136
|
-
* The declared shape of one outcome, exported so tests can validate real results.
|
|
137
|
-
*
|
|
138
|
-
* Split by `kind` instead of one flat object. The flat form could only require
|
|
139
|
-
* `kind` and `id`, so a foreground result that omitted `exitCode` was still
|
|
140
|
-
* "valid" and the schema proved nothing about the fields the model reads.
|
|
141
|
-
*
|
|
142
|
-
* `signal` is nullable because `child_process` reports `null` whenever the child
|
|
143
|
-
* exited on its own — that is every successful run. Declaring it `string` made
|
|
144
|
-
* the registry reject the tool's own normal output: `createSuccessResult()`
|
|
145
|
-
* validates before rendering, so **every** clean exit surfaced to the model as
|
|
146
|
-
* `tool "pstack_script" returned invalid output`.
|
|
147
|
-
*/
|
|
148
75
|
export declare const OUTPUT_SCHEMA: JsonSchemaNode;
|
|
149
76
|
/** The slices of the Cordis context this tool needs. */
|
|
150
77
|
export interface PstackScriptHost {
|
|
151
78
|
readonly tools: ToolsHost;
|
|
152
|
-
/** Resolves the Session's current directory; see `WorkingDirectoryHost`. */
|
|
153
79
|
readonly workingDirectory: WorkingDirectoryHost;
|
|
154
|
-
/**
|
|
155
|
-
* Optional, and read per call rather than snapshotted.
|
|
156
|
-
*
|
|
157
|
-
* A profile may mount a job controller after this row, so a value read once in
|
|
158
|
-
* `apply` would stay `undefined` forever. `ctx.get("jobs")` is rc.3's
|
|
159
|
-
* optional-service read: it returns `undefined` instead of throwing when the
|
|
160
|
-
* service is absent, which is why `jobs` is not declared in `inject`.
|
|
161
|
-
*/
|
|
162
80
|
readonly getJobs?: () => JobsHost | undefined;
|
|
163
81
|
}
|
|
164
82
|
/** Build the tool for one row. */
|
|
165
83
|
export declare function createPstackScriptTool(host: PstackScriptHost): ToolDefinition;
|
|
166
84
|
/** Cordis row name, used by Loader diagnostics. */
|
|
167
85
|
export declare const name = "pstack-script";
|
|
168
|
-
/**
|
|
169
|
-
* The hard dependencies.
|
|
170
|
-
*
|
|
171
|
-
* `tools` is the registry this row registers into; `workingDirectory` is what
|
|
172
|
-
* turns the tool's `cwd` argument and its omitted case into the Session's
|
|
173
|
-
* directory. Both are always present in a profile that has an Agent at all.
|
|
174
|
-
*
|
|
175
|
-
* `jobs` is deliberately absent: a composition without a job controller still
|
|
176
|
-
* registers the tool, and only `background: true` is refused. Declaring `jobs`
|
|
177
|
-
* here would keep the whole fiber inactive in every profile that has no job
|
|
178
|
-
* controller, which is most of them.
|
|
179
|
-
*/
|
|
86
|
+
/** Hard dependencies: the tool registry and the session directory. `jobs` is optional and read per call. */
|
|
180
87
|
export declare const inject: string[];
|
|
181
|
-
/**
|
|
182
|
-
* Register `pstack_script` for this row.
|
|
183
|
-
*
|
|
184
|
-
* `inject` is what makes `ctx.tools` readable at all: without it Cordis runs
|
|
185
|
-
* `apply` immediately and the service proxy throws
|
|
186
|
-
* `cannot get property "tools" without inject`, so the row would register nothing
|
|
187
|
-
* in any profile.
|
|
188
|
-
*/
|
|
88
|
+
/** Register `pstack_script` for this row. */
|
|
189
89
|
export declare function apply(ctx: PstackScriptHost & {
|
|
190
90
|
get?: (name: string) => JobsHost | undefined;
|
|
191
|
-
}): void;
|
|
192
|
-
//#endregion
|
|
193
|
-
//# sourceMappingURL=script.d.mts.map
|
|
91
|
+
}): void;
|