@senpiper/sp-agent 0.1.10 → 0.1.11

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.
Files changed (86) hide show
  1. package/INSTALL.md +36 -24
  2. package/README.md +13 -13
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +4 -4
  5. package/dist/cli.js.map +1 -1
  6. package/dist/distribution.d.ts +2 -2
  7. package/dist/distribution.d.ts.map +1 -1
  8. package/dist/distribution.js +1 -1
  9. package/dist/distribution.js.map +1 -1
  10. package/dist/extension-identity.generated.d.ts +3 -3
  11. package/dist/extension-identity.generated.d.ts.map +1 -1
  12. package/dist/extension-identity.generated.js +3 -3
  13. package/dist/extension-identity.generated.js.map +1 -1
  14. package/dist/install-sp.sh +9 -9
  15. package/dist/release-manager.d.ts.map +1 -1
  16. package/dist/release-manager.js +2 -2
  17. package/dist/release-manager.js.map +1 -1
  18. package/dist/runtime-cli.d.ts.map +1 -1
  19. package/dist/runtime-cli.js +4 -4
  20. package/dist/runtime-cli.js.map +1 -1
  21. package/dist/sdk.d.ts +1 -1
  22. package/dist/sdk.d.ts.map +1 -1
  23. package/dist/sdk.js +5 -5
  24. package/dist/sdk.js.map +1 -1
  25. package/dist/session-manager.d.ts +1 -1
  26. package/dist/session-manager.d.ts.map +1 -1
  27. package/dist/session-manager.js +15 -15
  28. package/dist/session-manager.js.map +1 -1
  29. package/dist/sp-web.d.ts.map +1 -1
  30. package/dist/sp-web.js +2 -2
  31. package/dist/sp-web.js.map +1 -1
  32. package/dist/version.d.ts +1 -1
  33. package/dist/version.d.ts.map +1 -1
  34. package/dist/version.js +1 -1
  35. package/dist/version.js.map +1 -1
  36. package/node_modules/@senpiper/pi-coding-agent/dist/bundle/chunks/{chunk-LUSUF4ZH.js → chunk-VVKE4QZJ.js} +1 -1
  37. package/node_modules/@senpiper/pi-coding-agent/dist/bundle/cli.js +1 -1
  38. package/node_modules/@senpiper/pi-coding-agent/dist/bundle/index.js +1 -1
  39. package/node_modules/@senpiper/pi-coding-agent/dist/bundle/rpc-entry.js +1 -1
  40. package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  41. package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  42. package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/baseten.json +1 -1
  43. package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
  44. package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
  45. package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/kimi-coding.json +1 -1
  46. package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
  47. package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
  48. package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  49. package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan-cn.json +1 -1
  50. package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan.json +1 -1
  51. package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/together.json +1 -1
  52. package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  53. package/node_modules/@senpiper/pi-coding-agent/package.json +1 -1
  54. package/node_modules/@senpiper/sp-agent-extensions/CHANGELOG.md +17 -0
  55. package/node_modules/@senpiper/sp-agent-extensions/CONCURRENT_SESSIONS.md +9 -9
  56. package/node_modules/@senpiper/sp-agent-extensions/TERMINAL_WEB_BRIDGE.md +28 -9
  57. package/node_modules/@senpiper/sp-agent-extensions/dist/cli-commands.d.ts.map +1 -1
  58. package/node_modules/@senpiper/sp-agent-extensions/dist/cli-commands.js +5 -5
  59. package/node_modules/@senpiper/sp-agent-extensions/dist/cli-commands.js.map +1 -1
  60. package/node_modules/@senpiper/sp-agent-extensions/dist/gateway.d.ts +1 -1
  61. package/node_modules/@senpiper/sp-agent-extensions/dist/gateway.d.ts.map +1 -1
  62. package/node_modules/@senpiper/sp-agent-extensions/dist/gateway.js +18 -18
  63. package/node_modules/@senpiper/sp-agent-extensions/dist/gateway.js.map +1 -1
  64. package/node_modules/@senpiper/sp-agent-extensions/dist/index.d.ts +1 -1
  65. package/node_modules/@senpiper/sp-agent-extensions/dist/index.d.ts.map +1 -1
  66. package/node_modules/@senpiper/sp-agent-extensions/dist/index.js +1 -1
  67. package/node_modules/@senpiper/sp-agent-extensions/dist/index.js.map +1 -1
  68. package/node_modules/@senpiper/sp-agent-extensions/dist/login-command.d.ts.map +1 -1
  69. package/node_modules/@senpiper/sp-agent-extensions/dist/login-command.js +9 -9
  70. package/node_modules/@senpiper/sp-agent-extensions/dist/login-command.js.map +1 -1
  71. package/node_modules/@senpiper/sp-agent-extensions/dist/sp-web-launcher.d.ts +27 -0
  72. package/node_modules/@senpiper/sp-agent-extensions/dist/sp-web-launcher.d.ts.map +1 -1
  73. package/node_modules/@senpiper/sp-agent-extensions/dist/sp-web-launcher.js +270 -28
  74. package/node_modules/@senpiper/sp-agent-extensions/dist/sp-web-launcher.js.map +1 -1
  75. package/node_modules/@senpiper/sp-agent-extensions/dist/startup-header.d.ts.map +1 -1
  76. package/node_modules/@senpiper/sp-agent-extensions/dist/startup-header.js +12 -19
  77. package/node_modules/@senpiper/sp-agent-extensions/dist/startup-header.js.map +1 -1
  78. package/node_modules/@senpiper/sp-agent-extensions/dist/terminal-web-bridge.d.ts +1 -1
  79. package/node_modules/@senpiper/sp-agent-extensions/dist/terminal-web-bridge.d.ts.map +1 -1
  80. package/node_modules/@senpiper/sp-agent-extensions/dist/terminal-web-bridge.js +11 -9
  81. package/node_modules/@senpiper/sp-agent-extensions/dist/terminal-web-bridge.js.map +1 -1
  82. package/node_modules/@senpiper/sp-agent-extensions/dist/web-command.d.ts.map +1 -1
  83. package/node_modules/@senpiper/sp-agent-extensions/dist/web-command.js +36 -10
  84. package/node_modules/@senpiper/sp-agent-extensions/dist/web-command.js.map +1 -1
  85. package/node_modules/@senpiper/sp-agent-extensions/package.json +3 -2
  86. package/package.json +7 -6
package/INSTALL.md CHANGED
@@ -1,13 +1,13 @@
1
- # Install SP Agent and SP Web
1
+ # Install Senpiper Workbench
2
2
 
3
- This guide targets `@senpiper/sp-agent@0.1.7` and newer, which include SP Web.
3
+ This guide targets `@senpiper/sp-agent@0.1.7` and newer, which include the web workspace.
4
4
 
5
- Gateway: **https://sp-api.staging.senpiper.com/**
5
+ Senpiper Gateway: **https://sp-api.staging.senpiper.com/**
6
6
 
7
7
  ## Requirements
8
8
 
9
9
  - Node.js **22.19.0 or newer**, with npm. Node.js 24 LTS is recommended.
10
- - An SP Gateway API key supplied by your administrator.
10
+ - A Senpiper Gateway API key supplied by your administrator.
11
11
  - A terminal and a web browser.
12
12
 
13
13
  The workspace terminal uses a native PTY. Linux source builds require Python 3,
@@ -22,8 +22,8 @@ npm install --global @senpiper/sp-agent
22
22
 
23
23
  One package installs both commands:
24
24
 
25
- - `sp`: the terminal coding agent.
26
- - `sp-web`: the browser workspace server.
25
+ - `sp`: the terminal application.
26
+ - `sp-web`: the web workspace server.
27
27
 
28
28
  Check the installation:
29
29
 
@@ -48,16 +48,16 @@ npm install --global --allow-scripts=node-pty @senpiper/sp-agent
48
48
  Without that approval, the applications can install while the workspace
49
49
  terminal remains unavailable. Do not use `--ignore-scripts` if you need the PTY.
50
50
 
51
- ## 2. Connect to SP Gateway
51
+ ## 2. Connect to Senpiper Gateway
52
52
 
53
- Start SP from your project directory:
53
+ Start Senpiper Workbench from your project directory:
54
54
 
55
55
  ```bash
56
56
  cd /path/to/your/project
57
57
  sp
58
58
  ```
59
59
 
60
- Inside SP, enter:
60
+ Inside Senpiper Workbench, enter:
61
61
 
62
62
  ```text
63
63
  /login https://sp-api.staging.senpiper.com/
@@ -66,10 +66,10 @@ Inside SP, enter:
66
66
  Paste your gateway API key into the **masked API-key prompt**. Do not put the
67
67
  key in a chat message, README, or shell command.
68
68
 
69
- SP adds `/v1` to the supplied gateway URL, retrieves the available models,
69
+ Senpiper Workbench adds `/v1` to the supplied gateway URL, retrieves the available models,
70
70
  and selects the first model.
71
71
 
72
- Use `/model` in SP to choose another available model. To inspect the model
72
+ Use `/model` in Senpiper Workbench to choose another available model. To inspect the model
73
73
  catalog from a separate terminal:
74
74
 
75
75
  ```bash
@@ -82,20 +82,32 @@ For CLI-only setup, the equivalent command is:
82
82
  sp login --gateway-url https://sp-api.staging.senpiper.com/
83
83
  ```
84
84
 
85
- That CLI prompt is not masked. Prefer `/login` inside SP when entering a key.
85
+ That CLI prompt is not masked. Prefer `/login` inside Senpiper Workbench when entering a key.
86
86
 
87
- ## 3. Open SP Web
87
+ ## 3. Open the web workspace
88
88
 
89
- Interactive SP starts the web sidecar automatically. Open:
89
+ Interactive Senpiper Workbench starts the web sidecar automatically. Open:
90
90
 
91
91
  **http://127.0.0.1:30141**
92
92
 
93
- Keep an SP instance running to send prompts and manage live sessions. SP Web
94
- connects to SP; it does not create a second writer for the same history file.
93
+ Keep a Senpiper Workbench instance running to send prompts and manage live sessions. The web workspace
94
+ connects to Senpiper Workbench; it does not create a second writer for the same history file.
95
95
 
96
96
  The workspace includes chat, native questions, files, Git diffs, and a terminal.
97
97
  Commits and permanent thread deletion require confirmation.
98
98
 
99
+ Inside the terminal application:
100
+
101
+ - `/web` or `/web on` starts the web UI if needed and opens it in your browser.
102
+ - `/web off` stops the managed web server for this profile. Terminal agent
103
+ sessions and Senpiper Gateway keep running.
104
+
105
+ Stopping is temporary: `/web` starts it again, and the next interactive `sp`
106
+ launch can start it automatically. The server is shared by terminals using the
107
+ same profile, so stopping it disconnects their browsers too. Any workspace
108
+ shells running inside the web server may end; save work before stopping.
109
+ For a server you started manually with `sp-web`, use Ctrl+C in its terminal.
110
+
99
111
  ### Manual web startup
100
112
 
101
113
  If you want to start the server yourself, disable automatic startup first:
@@ -120,17 +132,17 @@ Open `http://127.0.0.1:30142` yourself.
120
132
 
121
133
  ## Configuration and credentials
122
134
 
123
- SP stores its configuration and history under:
135
+ Senpiper Workbench stores its configuration and history under:
124
136
 
125
137
  ```text
126
138
  ~/.sp/agent/
127
139
  ```
128
140
 
129
141
  Use `SP_CODING_AGENT_DIR` to select another profile. Set it consistently for
130
- SP and any manually started SP Web process.
142
+ Senpiper Workbench and any manually started web workspace process.
131
143
 
132
- The gateway key stays on the machine running SP. Browser users do not need to
133
- paste that key into SP Web. If web authentication is enabled with
144
+ The gateway key stays on the machine running Senpiper Workbench. Browser users do not need to
145
+ paste that key into the web workspace. If web authentication is enabled with
134
146
  `SP_WEB_PASSWORD`, use username **`sp`** and the configured web password.
135
147
  The web password and the gateway API key are different credentials.
136
148
 
@@ -147,7 +159,7 @@ Update both applications together:
147
159
  npm install --global @senpiper/sp-agent@latest
148
160
  ```
149
161
 
150
- Use the npm 12 script-approval flag above when applicable. Restart SP and its
162
+ Use the npm 12 script-approval flag above when applicable. Restart Senpiper Workbench and its
151
163
  web sidecar after updating, then refresh the browser. Existing processes do
152
164
  not load replacement code automatically.
153
165
 
@@ -166,9 +178,9 @@ directory unless you intend to delete its credentials, settings, and history.
166
178
  | --- | --- |
167
179
  | `sp` or `sp-web` is not found | Open a new terminal and ensure your Node version manager's global npm bin directory is on `PATH`. |
168
180
  | npm reports `EACCES` | Use a Node version manager or a user-writable npm prefix instead of a system-owned global installation. |
169
- | `sp` is older than `0.1.7` | You have a release from before bundled SP Web. Check that the new release is available in your npm registry. |
181
+ | `sp` is older than `0.1.7` | You have a release from before the bundled web workspace. Check that the new release is available in your npm registry. |
170
182
  | Login returns `401` or `403` | Ask your administrator to verify the gateway API key and access permissions, then repeat `/login`. |
171
183
  | No gateway models appear | Check gateway connectivity and repeat `/login` to synchronize the catalog. |
172
- | SP Web has no live session | Start `sp` in the project and confirm both processes use the same SP profile. |
173
- | Port `30141` is already in use | Open the existing SP Web instance, or choose another port for a manually started server. |
184
+ | The web workspace has no live session | Start `sp` in the project and confirm both processes use the same Senpiper Workbench profile. |
185
+ | Port `30141` is already in use | Open the existing web workspace, or choose another port for a manually started server. |
174
186
  | Workspace terminal is unavailable | Check build tools and npm install-script approval for `node-pty`. |
package/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # @senpiper/sp-agent
2
2
 
3
- SP is Senpiper's coding agent. This package includes the `sp` terminal application and SP Web, a browser workspace for the same sessions. It uses `~/.sp/agent` and routes model traffic through `sp-gateway`.
3
+ Senpiper Workbench is Senpiper's Pi-based coding agent and web interface. This package includes the `sp` terminal application and the web workspace for the same sessions. It uses `~/.sp/agent` and routes model traffic through Senpiper Gateway (`sp-gateway`).
4
4
 
5
5
  ## Install
6
6
 
7
7
  Requires Node.js 22.19 or newer.
8
8
 
9
9
  See [the installation guide](INSTALL.md) for setup with
10
- `https://sp-api.staging.senpiper.com/`, gateway login, and SP Web.
10
+ `https://sp-api.staging.senpiper.com/`, gateway login, and the web workspace.
11
11
 
12
12
  ```bash
13
13
  npm install --global @senpiper/sp-agent
@@ -17,13 +17,13 @@ sp
17
17
  One installation provides both commands:
18
18
 
19
19
  ```bash
20
- sp # Start the terminal agent and its SP Web sidecar
21
- sp-web # Start SP Web directly
20
+ sp # Start the terminal agent and its web sidecar
21
+ sp-web # Start the web workspace directly
22
22
  ```
23
23
 
24
- SP Web connects to running SP sessions. SP owns the agents and their history files; the web UI does not create a competing writer. Run `sp-web --help` for browser, address, port, and authentication options.
24
+ The web workspace connects to running terminal sessions. Senpiper Workbench owns the agents and their history files; the web UI does not create a competing writer. Run `sp-web --help` for browser, address, port, and authentication options.
25
25
 
26
- The package bundles the SP runtime and required extensions, and installs the exact `@senpiper/sp-web` dependency automatically. You do not need a separate web installation.
26
+ The package bundles the Senpiper Workbench runtime and required extensions, and installs the exact `@senpiper/sp-web` dependency automatically. You do not need a separate web installation.
27
27
 
28
28
  The workspace terminal uses `node-pty`. If its installer cannot use a prebuilt binary for your platform, npm compiles it locally. Linux source builds need Python 3, `make`, and a C/C++ compiler. Do not disable install scripts if you need the workspace terminal.
29
29
 
@@ -35,13 +35,13 @@ npm install --global --allow-scripts=node-pty @senpiper/sp-agent
35
35
 
36
36
  The ordinary install still provides both applications, but a blocked native build can leave the workspace terminal unavailable.
37
37
 
38
- Set `SP_WEB_DISABLE=1` to run SP without automatically starting the web sidecar. This does not uninstall SP Web.
38
+ Set `SP_WEB_DISABLE=1` to run Senpiper Workbench without automatically starting the web sidecar. This does not uninstall the web workspace.
39
39
 
40
40
  ## Publishing
41
41
 
42
- Build SP Web in a disposable copy of its repository, not a checkout running a development server. Pack the production build with `npm pack --ignore-scripts`.
42
+ Build the web workspace in a disposable copy of its repository, not a checkout running a development server. Pack the production build with `npm pack --ignore-scripts`.
43
43
 
44
- Set the intended source versions before building. Pass the web tarball and its build lockfile to the SP release command. The dry run validates the web artifact, builds the SP tarball, and checks a clean global installation without publishing:
44
+ Set the intended source versions before building. Pass the web tarball and its build lockfile to the Senpiper Workbench release command. The dry run validates the web artifact, builds the Senpiper Workbench tarball, and checks a clean global installation without publishing:
45
45
 
46
46
  ```bash
47
47
  node scripts/publish-sp-packages.mjs --dry-run \
@@ -51,7 +51,7 @@ node scripts/publish-sp-packages.mjs --dry-run \
51
51
  --output /absolute/path/release-artifacts
52
52
  ```
53
53
 
54
- Copy the exact validated web tarball into that output directory alongside the SP tarball. Keep exactly one tarball for each package there. Log in with an npm account that has write access to the `@senpiper` scope, then publish from an interactive terminal:
54
+ Copy the exact validated web tarball into that output directory alongside the Senpiper Workbench tarball. Keep exactly one tarball for each package there. Log in with an npm account that has write access to the `@senpiper` scope, then publish from an interactive terminal:
55
55
 
56
56
  ```bash
57
57
  npm run login:sp:npm
@@ -60,7 +60,7 @@ node scripts/publish-sp-npm-artifacts.mjs /absolute/path/release-artifacts --che
60
60
  node scripts/publish-sp-npm-artifacts.mjs /absolute/path/release-artifacts
61
61
  ```
62
62
 
63
- The artifact publisher checks registry hashes, publishes Web first and then SP, and verifies each published hash. Complete npm's interactive 2FA prompt when requested. `--check` checks artifacts and registry state without publishing. If interrupted, rerun with the same artifacts; matching published versions are verified and skipped. Do not rebuild between attempts. The private runtime and extension packages remain bundled and do not need separate public releases.
63
+ The artifact publisher checks registry hashes, publishes the web workspace first and then the agent, and verifies each published hash. Complete npm's interactive 2FA prompt when requested. `--check` checks artifacts and registry state without publishing. If interrupted, rerun with the same artifacts; matching published versions are verified and skipped. Do not rebuild between attempts. The private runtime and extension packages remain bundled and do not need separate public releases.
64
64
 
65
65
  The private `packages/sp-web-contract` workspace only records the required web version for source development. It is not the web application and is never used as the release artifact.
66
66
 
@@ -68,7 +68,7 @@ The supported programmatic entry point is `@senpiper/sp-agent/sdk`. It does not
68
68
 
69
69
  ## Concurrent web sessions
70
70
 
71
- Interactive SP supplies an instance-owned session manager to its required bridge extension. Web `create_session {cwd}` and `resume_session {sessionFile}` return `{sessionId}` for an independently running session. Select its existing-format discovery descriptor to send commands. Terminal replacement and browser disconnection leave other sessions running.
71
+ Interactive Senpiper Workbench supplies an instance-owned session manager to its required bridge extension. Web `create_session {cwd}` and `resume_session {sessionFile}` return `{sessionId}` for an independently running session. Select its existing-format discovery descriptor to send commands. Terminal replacement and browser disconnection leave other sessions running.
72
72
 
73
73
  SDK hosts can use the same verified factory:
74
74
 
@@ -88,7 +88,7 @@ try {
88
88
 
89
89
  ## Third-party notices
90
90
 
91
- SP includes Pi code under the MIT license below. SP Web's upstream license and T3 attribution are included in the installed `@senpiper/sp-web` package as `LICENSE` and `THIRD_PARTY_NOTICES.md`. Other dependencies retain their own licenses.
91
+ Senpiper Workbench includes Pi code under the MIT license below. The web workspace's upstream license and T3 attribution are included in the installed `@senpiper/sp-web` package as `LICENSE` and `THIRD_PARTY_NOTICES.md`. Other dependencies retain their own licenses.
92
92
 
93
93
  ```text
94
94
  MIT License
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"","sourcesContent":["#!/usr/bin/env node\nimport { configureSpEnvironment } from \"./environment.ts\";\nimport { handleSpReleaseCommand } from \"./release-manager.ts\";\nimport { runSpRuntime } from \"./runtime-cli.ts\";\nimport { SP_AGENT_VERSION } from \"./version.ts\";\n\nfunction printHelp() {\n\tconsole.log(`sp-agent ${SP_AGENT_VERSION}\n\nUsage:\n sp Start the interactive terminal\n sp -p <prompt> Run a one-shot prompt\n sp --mode json|rpc Select a machine-readable mode\n sp --list-models List canonical sp-gateway models\n sp login|logout Manage sp-gateway credentials\n sp update|rollback|repair Manage the active verified release\n sp --help Show this help\n sp-web Start the bundled browser workspace\n\nConfiguration: ~/.sp/agent (override with SP_CODING_AGENT_DIR)`);\n}\n\nasync function run() {\n\tconfigureSpEnvironment();\n\tprocess.title = \"sp\";\n\tconst args = process.argv.slice(2);\n\tif (args.length === 1 && (args[0] === \"--version\" || args[0] === \"-v\")) {\n\t\tconsole.log(SP_AGENT_VERSION);\n\t\treturn;\n\t}\n\tif (args.length === 1 && (args[0] === \"--help\" || args[0] === \"-h\")) {\n\t\tprintHelp();\n\t\treturn;\n\t}\n\tif (await handleSpReleaseCommand(args)) return;\n\tawait runSpRuntime(args);\n}\n\nrun().catch((error) => {\n\tconsole.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n\tprocess.exitCode = 1;\n});\n"]}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"","sourcesContent":["#!/usr/bin/env node\nimport { configureSpEnvironment } from \"./environment.ts\";\nimport { handleSpReleaseCommand } from \"./release-manager.ts\";\nimport { runSpRuntime } from \"./runtime-cli.ts\";\nimport { SP_AGENT_VERSION } from \"./version.ts\";\n\nfunction printHelp() {\n\tconsole.log(`Senpiper Workbench ${SP_AGENT_VERSION}\n\nUsage:\n sp Start the interactive terminal\n sp -p <prompt> Run a one-shot prompt\n sp --mode json|rpc Select a machine-readable mode\n sp --list-models List canonical Senpiper Gateway models\n sp login|logout Manage Senpiper Gateway credentials\n sp update|rollback|repair Manage the active verified release\n sp --help Show this help\n sp-web Start the Senpiper Workbench web workspace\n\nConfiguration: ~/.sp/agent (override with SP_CODING_AGENT_DIR)`);\n}\n\nasync function run() {\n\tconfigureSpEnvironment();\n\tprocess.title = \"sp\";\n\tconst args = process.argv.slice(2);\n\tif (args.length === 1 && (args[0] === \"--version\" || args[0] === \"-v\")) {\n\t\tconsole.log(SP_AGENT_VERSION);\n\t\treturn;\n\t}\n\tif (args.length === 1 && (args[0] === \"--help\" || args[0] === \"-h\")) {\n\t\tprintHelp();\n\t\treturn;\n\t}\n\tif (await handleSpReleaseCommand(args)) return;\n\tawait runSpRuntime(args);\n}\n\nrun().catch((error) => {\n\tconsole.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n\tprocess.exitCode = 1;\n});\n"]}
package/dist/cli.js CHANGED
@@ -4,17 +4,17 @@ import { handleSpReleaseCommand } from "./release-manager.js";
4
4
  import { runSpRuntime } from "./runtime-cli.js";
5
5
  import { SP_AGENT_VERSION } from "./version.js";
6
6
  function printHelp() {
7
- console.log(`sp-agent ${SP_AGENT_VERSION}
7
+ console.log(`Senpiper Workbench ${SP_AGENT_VERSION}
8
8
 
9
9
  Usage:
10
10
  sp Start the interactive terminal
11
11
  sp -p <prompt> Run a one-shot prompt
12
12
  sp --mode json|rpc Select a machine-readable mode
13
- sp --list-models List canonical sp-gateway models
14
- sp login|logout Manage sp-gateway credentials
13
+ sp --list-models List canonical Senpiper Gateway models
14
+ sp login|logout Manage Senpiper Gateway credentials
15
15
  sp update|rollback|repair Manage the active verified release
16
16
  sp --help Show this help
17
- sp-web Start the bundled browser workspace
17
+ sp-web Start the Senpiper Workbench web workspace
18
18
 
19
19
  Configuration: ~/.sp/agent (override with SP_CODING_AGENT_DIR)`);
20
20
  }
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,SAAS,SAAS,GAAG;IACpB,OAAO,CAAC,GAAG,CAAC,YAAY,gBAAgB;;;;;;;;;;;;+DAYsB,CAAC,CAAC;AAAA,CAChE;AAED,KAAK,UAAU,GAAG,GAAG;IACpB,sBAAsB,EAAE,CAAC;IACzB,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IACrB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC9B,OAAO;IACR,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;QACrE,SAAS,EAAE,CAAC;QACZ,OAAO;IACR,CAAC;IACD,IAAI,MAAM,sBAAsB,CAAC,IAAI,CAAC;QAAE,OAAO;IAC/C,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;AAAA,CACzB;AAED,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;IACtB,OAAO,CAAC,KAAK,CAAC,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AAAA,CACrB,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\nimport { configureSpEnvironment } from \"./environment.ts\";\nimport { handleSpReleaseCommand } from \"./release-manager.ts\";\nimport { runSpRuntime } from \"./runtime-cli.ts\";\nimport { SP_AGENT_VERSION } from \"./version.ts\";\n\nfunction printHelp() {\n\tconsole.log(`sp-agent ${SP_AGENT_VERSION}\n\nUsage:\n sp Start the interactive terminal\n sp -p <prompt> Run a one-shot prompt\n sp --mode json|rpc Select a machine-readable mode\n sp --list-models List canonical sp-gateway models\n sp login|logout Manage sp-gateway credentials\n sp update|rollback|repair Manage the active verified release\n sp --help Show this help\n sp-web Start the bundled browser workspace\n\nConfiguration: ~/.sp/agent (override with SP_CODING_AGENT_DIR)`);\n}\n\nasync function run() {\n\tconfigureSpEnvironment();\n\tprocess.title = \"sp\";\n\tconst args = process.argv.slice(2);\n\tif (args.length === 1 && (args[0] === \"--version\" || args[0] === \"-v\")) {\n\t\tconsole.log(SP_AGENT_VERSION);\n\t\treturn;\n\t}\n\tif (args.length === 1 && (args[0] === \"--help\" || args[0] === \"-h\")) {\n\t\tprintHelp();\n\t\treturn;\n\t}\n\tif (await handleSpReleaseCommand(args)) return;\n\tawait runSpRuntime(args);\n}\n\nrun().catch((error) => {\n\tconsole.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n\tprocess.exitCode = 1;\n});\n"]}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,SAAS,SAAS,GAAG;IACpB,OAAO,CAAC,GAAG,CAAC,sBAAsB,gBAAgB;;;;;;;;;;;;+DAYY,CAAC,CAAC;AAAA,CAChE;AAED,KAAK,UAAU,GAAG,GAAG;IACpB,sBAAsB,EAAE,CAAC;IACzB,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IACrB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC9B,OAAO;IACR,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;QACrE,SAAS,EAAE,CAAC;QACZ,OAAO;IACR,CAAC;IACD,IAAI,MAAM,sBAAsB,CAAC,IAAI,CAAC;QAAE,OAAO;IAC/C,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;AAAA,CACzB;AAED,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;IACtB,OAAO,CAAC,KAAK,CAAC,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AAAA,CACrB,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\nimport { configureSpEnvironment } from \"./environment.ts\";\nimport { handleSpReleaseCommand } from \"./release-manager.ts\";\nimport { runSpRuntime } from \"./runtime-cli.ts\";\nimport { SP_AGENT_VERSION } from \"./version.ts\";\n\nfunction printHelp() {\n\tconsole.log(`Senpiper Workbench ${SP_AGENT_VERSION}\n\nUsage:\n sp Start the interactive terminal\n sp -p <prompt> Run a one-shot prompt\n sp --mode json|rpc Select a machine-readable mode\n sp --list-models List canonical Senpiper Gateway models\n sp login|logout Manage Senpiper Gateway credentials\n sp update|rollback|repair Manage the active verified release\n sp --help Show this help\n sp-web Start the Senpiper Workbench web workspace\n\nConfiguration: ~/.sp/agent (override with SP_CODING_AGENT_DIR)`);\n}\n\nasync function run() {\n\tconfigureSpEnvironment();\n\tprocess.title = \"sp\";\n\tconst args = process.argv.slice(2);\n\tif (args.length === 1 && (args[0] === \"--version\" || args[0] === \"-v\")) {\n\t\tconsole.log(SP_AGENT_VERSION);\n\t\treturn;\n\t}\n\tif (args.length === 1 && (args[0] === \"--help\" || args[0] === \"-h\")) {\n\t\tprintHelp();\n\t\treturn;\n\t}\n\tif (await handleSpReleaseCommand(args)) return;\n\tawait runSpRuntime(args);\n}\n\nrun().catch((error) => {\n\tconsole.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n\tprocess.exitCode = 1;\n});\n"]}
@@ -36,7 +36,7 @@ export declare function createSpExtensionRunnerOptions(extensions: readonly Exte
36
36
  export declare function createSpMainOptions(): Promise<MainOptions>;
37
37
  export declare const requiredExtension: {
38
38
  readonly name: "@senpiper/sp-agent-extensions";
39
- readonly version: "0.1.4";
40
- readonly digest: "sha256:f4211efa0ca9b8f37d2fa6b912a52f83bf96eda494c8e3de16cad2c307c4511f";
39
+ readonly version: "0.1.5";
40
+ readonly digest: "sha256:c526026def1e6b4b5bf777b9b90583fef1d18bf0793b99821b653a592b771b48";
41
41
  };
42
42
  //# sourceMappingURL=distribution.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"distribution.d.ts","sourceRoot":"","sources":["../src/distribution.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACX,SAAS,EACT,gBAAgB,EAChB,sBAAsB,EACtB,WAAW,EACX,mBAAmB,EACnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAK9E,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAIhD,eAAO,MAAM,wBAAwB,sBAAsB,CAAC;AAO5D,UAAU,yBAAyB;IAClC,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5D;AAED,MAAM,WAAW,uBAAuB;IACvC,sBAAsB,EAAE,CAAC,OAAO,CAAC,EAAE,wBAAwB,KAAK,gBAAgB,CAAC;IACjF,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACtD,mBAAmB,EAAE,MAAM,OAAO,CAAC;IACnC,kBAAkB,EAAE,MAAM,OAAO,CAAC;IAClC,sBAAsB,EAAE,MAAM,CAAC;CAC/B;AAED,UAAU,kCAAkC;IAC3C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,yBAAyB,CAAC;IAC7C,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,UAAU,4BAA6B,SAAQ,kCAAkC;IAChF,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1D;AAoDD,wBAAgB,+BAA+B,CAAC,OAAO,GAAE,kCAAuC,QAqC/F;AAoBD,wBAAsB,qBAAqB,CAAC,OAAO,GAAE,4BAAiC,oCAqBrF;AAED,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,uBAAuB,GAAG,mBAAmB,CASnG;AAED,wBAAgB,8BAA8B,CAAC,UAAU,EAAE,SAAS,SAAS,EAAE,GAAG,sBAAsB,CAevG;AAED,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,WAAW,CAAC,CAqBhE;AAED,eAAO,MAAM,iBAAiB;;;;CAIpB,CAAC","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, join, parse, relative } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type {\n\tExtension,\n\tExtensionFactory,\n\tExtensionRunnerOptions,\n\tMainOptions,\n\tModelProviderPolicy,\n} from \"@senpiper/pi-coding-agent\";\nimport type { TerminalWebBridgeOptions } from \"@senpiper/sp-agent-extensions\";\nimport { EMBEDDED_REQUIRED_EXTENSION_IDENTITY } from \"./extension-identity.generated.ts\";\nimport { createSpSessionManager } from \"./sdk.ts\";\nimport { spWriterLeases } from \"./writer-leases.ts\";\n\nexport { configureSpEnvironment } from \"./environment.ts\";\nexport { SP_AGENT_VERSION } from \"./version.ts\";\n\ndeclare const SP_AGENT_COMPILED: boolean;\n\nexport const REQUIRED_EXTENSION_OWNER = \"<inline:sp-agent>\";\n\ninterface PackageManifest {\n\tname?: string;\n\tversion?: string;\n}\n\ninterface EmbeddedExtensionIdentity {\n\trequired: { name: string; version: string };\n\tartifact: { name: string; version: string; digest: string };\n}\n\nexport interface RequiredExtensionModule {\n\tcreateSpAgentExtension: (options?: TerminalWebBridgeOptions) => ExtensionFactory;\n\thandleSpCommand: (args: string[]) => Promise<boolean>;\n\treadSpGatewayApiKey: () => unknown;\n\treadSpGatewayState: () => unknown;\n\tSP_GATEWAY_PROVIDER_ID: string;\n}\n\ninterface RequiredExtensionValidationOptions {\n\tcompiled?: boolean;\n\tembeddedIdentity?: EmbeddedExtensionIdentity;\n\tresolvedEntrypoint?: string;\n}\n\ninterface RequiredExtensionLoadOptions extends RequiredExtensionValidationOptions {\n\timportExtension?: (specifier: string) => Promise<unknown>;\n}\n\nfunction findPackageManifest(entrypoint: string) {\n\tlet directory = dirname(entrypoint);\n\tconst root = parse(directory).root;\n\twhile (directory !== root) {\n\t\tconst manifestPath = join(directory, \"package.json\");\n\t\tif (existsSync(manifestPath)) return manifestPath;\n\t\tdirectory = dirname(directory);\n\t}\n\treturn undefined;\n}\n\nfunction collectJavaScriptFiles(directory: string): string[] {\n\tconst files: string[] = [];\n\tfor (const entry of readdirSync(directory, { withFileTypes: true })) {\n\t\tconst path = join(directory, entry.name);\n\t\tif (entry.isDirectory()) files.push(...collectJavaScriptFiles(path));\n\t\telse if (entry.isFile() && entry.name.endsWith(\".js\")) files.push(path);\n\t}\n\treturn files.sort((left, right) => relative(directory, left).localeCompare(relative(directory, right)));\n}\n\nfunction digestArtifact(directory: string) {\n\tconst files = collectJavaScriptFiles(directory);\n\tif (files.length === 0) throw new Error(`Required extension artifact contains no JavaScript: ${directory}`);\n\tconst hash = createHash(\"sha256\");\n\tfor (const path of files) {\n\t\tconst artifactPath = relative(directory, path).replaceAll(\"\\\\\", \"/\");\n\t\tconst content = readFileSync(path);\n\t\thash.update(`${artifactPath}\\0${content.byteLength}\\0`);\n\t\thash.update(content);\n\t}\n\treturn `sha256:${hash.digest(\"hex\")}`;\n}\n\nfunction assertEmbeddedIdentity(identity: EmbeddedExtensionIdentity) {\n\tif (\n\t\tidentity.artifact.name !== identity.required.name ||\n\t\tidentity.artifact.version !== identity.required.version ||\n\t\t!/^sha256:[0-9a-f]{64}$/u.test(identity.artifact.digest)\n\t) {\n\t\tthrow new Error(\n\t\t\t`Required extension build identity mismatch: expected ${identity.required.name}@${identity.required.version}.`,\n\t\t);\n\t}\n}\n\nfunction isCompiledExecutable() {\n\treturn typeof SP_AGENT_COMPILED !== \"undefined\" && SP_AGENT_COMPILED;\n}\n\nexport function assertRequiredExtensionIdentity(options: RequiredExtensionValidationOptions = {}) {\n\tconst identity = options.embeddedIdentity ?? EMBEDDED_REQUIRED_EXTENSION_IDENTITY;\n\tassertEmbeddedIdentity(identity);\n\tif (options.compiled ?? isCompiledExecutable()) return;\n\n\tconst resolved = options.resolvedEntrypoint ?? import.meta.resolve(identity.required.name);\n\tif (!resolved.startsWith(\"file:\")) {\n\t\tthrow new Error(`Cannot verify required extension ${identity.required.name}: ${resolved}`);\n\t}\n\tconst entrypoint = fileURLToPath(resolved);\n\tconst manifestPath = findPackageManifest(entrypoint);\n\tif (!manifestPath) {\n\t\tthrow new Error(`Cannot find the manifest for required extension ${identity.required.name}.`);\n\t}\n\tconst packageDirectory = dirname(manifestPath);\n\tconst entrypointRelativePath = relative(packageDirectory, entrypoint);\n\tif (\n\t\tentrypointRelativePath === \"\" ||\n\t\tentrypointRelativePath === \"..\" ||\n\t\tentrypointRelativePath.startsWith(\"../\") ||\n\t\tentrypointRelativePath.startsWith(\"..\\\\\") ||\n\t\tisAbsolute(entrypointRelativePath)\n\t) {\n\t\tthrow new Error(`Required extension entrypoint is outside its package: ${entrypoint}`);\n\t}\n\tconst manifest = JSON.parse(readFileSync(manifestPath, \"utf8\")) as PackageManifest;\n\tif (manifest.name !== identity.required.name || manifest.version !== identity.required.version) {\n\t\tthrow new Error(\n\t\t\t`Required extension mismatch: expected ${identity.required.name}@${identity.required.version}, found ${manifest.name ?? \"unknown\"}@${manifest.version ?? \"unknown\"}.`,\n\t\t);\n\t}\n\tconst digest = digestArtifact(dirname(entrypoint));\n\tif (digest !== identity.artifact.digest) {\n\t\tthrow new Error(\n\t\t\t`Required extension authenticity check failed for ${identity.required.name}@${identity.required.version}.`,\n\t\t);\n\t}\n}\n\nfunction assertRequiredExtensionExports(value: unknown): asserts value is RequiredExtensionModule {\n\tif (typeof value !== \"object\" || value === null) {\n\t\tthrow new Error(`Required extension ${requiredExtension.name}@${requiredExtension.version} is invalid.`);\n\t}\n\tconst module = value as Record<string, unknown>;\n\tif (\n\t\ttypeof module.createSpAgentExtension !== \"function\" ||\n\t\ttypeof module.handleSpCommand !== \"function\" ||\n\t\ttypeof module.readSpGatewayApiKey !== \"function\" ||\n\t\ttypeof module.readSpGatewayState !== \"function\" ||\n\t\ttypeof module.SP_GATEWAY_PROVIDER_ID !== \"string\"\n\t) {\n\t\tthrow new Error(`Required extension ${requiredExtension.name}@${requiredExtension.version} is invalid.`);\n\t}\n}\n\nlet requiredExtensionPromise: Promise<RequiredExtensionModule> | undefined;\n\nexport async function loadRequiredExtension(options: RequiredExtensionLoadOptions = {}) {\n\tconst usesDefaultLoader = Object.keys(options).length === 0;\n\tif (usesDefaultLoader && requiredExtensionPromise) return requiredExtensionPromise;\n\n\tassertRequiredExtensionIdentity(options);\n\tconst compiled = options.compiled ?? isCompiledExecutable();\n\tconst specifier = compiled\n\t\t? EMBEDDED_REQUIRED_EXTENSION_IDENTITY.required.name\n\t\t: (options.resolvedEntrypoint ?? import.meta.resolve(EMBEDDED_REQUIRED_EXTENSION_IDENTITY.required.name));\n\tconst load = async () => {\n\t\tconst imported = options.importExtension\n\t\t\t? await options.importExtension(specifier)\n\t\t\t: compiled\n\t\t\t\t? await import(\"@senpiper/sp-agent-extensions\")\n\t\t\t\t: await import(specifier);\n\t\tassertRequiredExtensionExports(imported);\n\t\treturn imported;\n\t};\n\tconst promise = load();\n\tif (usesDefaultLoader) requiredExtensionPromise = promise;\n\treturn promise;\n}\n\nexport function createSpModelProviderPolicy(extension: RequiredExtensionModule): ModelProviderPolicy {\n\tconst configured = extension.readSpGatewayState() !== undefined;\n\tif (configured) extension.readSpGatewayApiKey();\n\treturn {\n\t\tallowedProviderIds: [extension.SP_GATEWAY_PROVIDER_ID],\n\t\trequiredProviderIds: configured ? [extension.SP_GATEWAY_PROVIDER_ID] : [],\n\t\tallowModelConfiguration: false,\n\t\tproviderOwners: { [extension.SP_GATEWAY_PROVIDER_ID]: REQUIRED_EXTENSION_OWNER },\n\t};\n}\n\nexport function createSpExtensionRunnerOptions(extensions: readonly Extension[]): ExtensionRunnerOptions {\n\tconst owner = extensions.find((extension) => extension.path === REQUIRED_EXTENSION_OWNER);\n\tif (!owner) throw new Error(\"Required SP extension did not load.\");\n\treturn {\n\t\tcommandOwnership: {\n\t\t\treservedCommandNames: [\"login\", \"web\"],\n\t\t\towners: new Map([\n\t\t\t\t[\"login\", owner],\n\t\t\t\t[\"web\", owner],\n\t\t\t]),\n\t\t},\n\t\tresourceOwnership: {\n\t\t\ttoolOwners: new Map([[\"ask_user_question\", owner]]),\n\t\t},\n\t};\n}\n\nexport async function createSpMainOptions(): Promise<MainOptions> {\n\tconst extension = await loadRequiredExtension();\n\tconst sessions = await createSpSessionManager();\n\treturn {\n\t\tsessionWriterLeaseProvider: spWriterLeases,\n\t\tonSessionHistoryRoot: (root, customSessionDir) => sessions.setHistoryRoot(root, customSessionDir),\n\t\tonSessionRuntime: (runtime) => sessions.attachRuntime(runtime),\n\t\textensionFactories: [\n\t\t\t{\n\t\t\t\tname: \"sp-agent\",\n\t\t\t\tfactory: extension.createSpAgentExtension({\n\t\t\t\t\tsessions,\n\t\t\t\t\twriterLeaseVersion: 1,\n\t\t\t\t\tonReady: (bridge) => sessions.trackBridge(bridge),\n\t\t\t\t}),\n\t\t\t},\n\t\t],\n\t\tincludeBuiltInExtensions: false,\n\t\tmodelProviderPolicy: createSpModelProviderPolicy(extension),\n\t\textensionRunnerOptionsResolver: createSpExtensionRunnerOptions,\n\t};\n}\n\nexport const requiredExtension = {\n\tname: EMBEDDED_REQUIRED_EXTENSION_IDENTITY.required.name,\n\tversion: EMBEDDED_REQUIRED_EXTENSION_IDENTITY.required.version,\n\tdigest: EMBEDDED_REQUIRED_EXTENSION_IDENTITY.artifact.digest,\n} as const;\n"]}
1
+ {"version":3,"file":"distribution.d.ts","sourceRoot":"","sources":["../src/distribution.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACX,SAAS,EACT,gBAAgB,EAChB,sBAAsB,EACtB,WAAW,EACX,mBAAmB,EACnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAK9E,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAIhD,eAAO,MAAM,wBAAwB,sBAAsB,CAAC;AAO5D,UAAU,yBAAyB;IAClC,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5D;AAED,MAAM,WAAW,uBAAuB;IACvC,sBAAsB,EAAE,CAAC,OAAO,CAAC,EAAE,wBAAwB,KAAK,gBAAgB,CAAC;IACjF,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACtD,mBAAmB,EAAE,MAAM,OAAO,CAAC;IACnC,kBAAkB,EAAE,MAAM,OAAO,CAAC;IAClC,sBAAsB,EAAE,MAAM,CAAC;CAC/B;AAED,UAAU,kCAAkC;IAC3C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,yBAAyB,CAAC;IAC7C,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,UAAU,4BAA6B,SAAQ,kCAAkC;IAChF,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1D;AAoDD,wBAAgB,+BAA+B,CAAC,OAAO,GAAE,kCAAuC,QAqC/F;AAoBD,wBAAsB,qBAAqB,CAAC,OAAO,GAAE,4BAAiC,oCAqBrF;AAED,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,uBAAuB,GAAG,mBAAmB,CASnG;AAED,wBAAgB,8BAA8B,CAAC,UAAU,EAAE,SAAS,SAAS,EAAE,GAAG,sBAAsB,CAevG;AAED,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,WAAW,CAAC,CAqBhE;AAED,eAAO,MAAM,iBAAiB;;;;CAIpB,CAAC","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, join, parse, relative } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type {\n\tExtension,\n\tExtensionFactory,\n\tExtensionRunnerOptions,\n\tMainOptions,\n\tModelProviderPolicy,\n} from \"@senpiper/pi-coding-agent\";\nimport type { TerminalWebBridgeOptions } from \"@senpiper/sp-agent-extensions\";\nimport { EMBEDDED_REQUIRED_EXTENSION_IDENTITY } from \"./extension-identity.generated.ts\";\nimport { createSpSessionManager } from \"./sdk.ts\";\nimport { spWriterLeases } from \"./writer-leases.ts\";\n\nexport { configureSpEnvironment } from \"./environment.ts\";\nexport { SP_AGENT_VERSION } from \"./version.ts\";\n\ndeclare const SP_AGENT_COMPILED: boolean;\n\nexport const REQUIRED_EXTENSION_OWNER = \"<inline:sp-agent>\";\n\ninterface PackageManifest {\n\tname?: string;\n\tversion?: string;\n}\n\ninterface EmbeddedExtensionIdentity {\n\trequired: { name: string; version: string };\n\tartifact: { name: string; version: string; digest: string };\n}\n\nexport interface RequiredExtensionModule {\n\tcreateSpAgentExtension: (options?: TerminalWebBridgeOptions) => ExtensionFactory;\n\thandleSpCommand: (args: string[]) => Promise<boolean>;\n\treadSpGatewayApiKey: () => unknown;\n\treadSpGatewayState: () => unknown;\n\tSP_GATEWAY_PROVIDER_ID: string;\n}\n\ninterface RequiredExtensionValidationOptions {\n\tcompiled?: boolean;\n\tembeddedIdentity?: EmbeddedExtensionIdentity;\n\tresolvedEntrypoint?: string;\n}\n\ninterface RequiredExtensionLoadOptions extends RequiredExtensionValidationOptions {\n\timportExtension?: (specifier: string) => Promise<unknown>;\n}\n\nfunction findPackageManifest(entrypoint: string) {\n\tlet directory = dirname(entrypoint);\n\tconst root = parse(directory).root;\n\twhile (directory !== root) {\n\t\tconst manifestPath = join(directory, \"package.json\");\n\t\tif (existsSync(manifestPath)) return manifestPath;\n\t\tdirectory = dirname(directory);\n\t}\n\treturn undefined;\n}\n\nfunction collectJavaScriptFiles(directory: string): string[] {\n\tconst files: string[] = [];\n\tfor (const entry of readdirSync(directory, { withFileTypes: true })) {\n\t\tconst path = join(directory, entry.name);\n\t\tif (entry.isDirectory()) files.push(...collectJavaScriptFiles(path));\n\t\telse if (entry.isFile() && entry.name.endsWith(\".js\")) files.push(path);\n\t}\n\treturn files.sort((left, right) => relative(directory, left).localeCompare(relative(directory, right)));\n}\n\nfunction digestArtifact(directory: string) {\n\tconst files = collectJavaScriptFiles(directory);\n\tif (files.length === 0) throw new Error(`Required extension artifact contains no JavaScript: ${directory}`);\n\tconst hash = createHash(\"sha256\");\n\tfor (const path of files) {\n\t\tconst artifactPath = relative(directory, path).replaceAll(\"\\\\\", \"/\");\n\t\tconst content = readFileSync(path);\n\t\thash.update(`${artifactPath}\\0${content.byteLength}\\0`);\n\t\thash.update(content);\n\t}\n\treturn `sha256:${hash.digest(\"hex\")}`;\n}\n\nfunction assertEmbeddedIdentity(identity: EmbeddedExtensionIdentity) {\n\tif (\n\t\tidentity.artifact.name !== identity.required.name ||\n\t\tidentity.artifact.version !== identity.required.version ||\n\t\t!/^sha256:[0-9a-f]{64}$/u.test(identity.artifact.digest)\n\t) {\n\t\tthrow new Error(\n\t\t\t`Required extension build identity mismatch: expected ${identity.required.name}@${identity.required.version}.`,\n\t\t);\n\t}\n}\n\nfunction isCompiledExecutable() {\n\treturn typeof SP_AGENT_COMPILED !== \"undefined\" && SP_AGENT_COMPILED;\n}\n\nexport function assertRequiredExtensionIdentity(options: RequiredExtensionValidationOptions = {}) {\n\tconst identity = options.embeddedIdentity ?? EMBEDDED_REQUIRED_EXTENSION_IDENTITY;\n\tassertEmbeddedIdentity(identity);\n\tif (options.compiled ?? isCompiledExecutable()) return;\n\n\tconst resolved = options.resolvedEntrypoint ?? import.meta.resolve(identity.required.name);\n\tif (!resolved.startsWith(\"file:\")) {\n\t\tthrow new Error(`Cannot verify required extension ${identity.required.name}: ${resolved}`);\n\t}\n\tconst entrypoint = fileURLToPath(resolved);\n\tconst manifestPath = findPackageManifest(entrypoint);\n\tif (!manifestPath) {\n\t\tthrow new Error(`Cannot find the manifest for required extension ${identity.required.name}.`);\n\t}\n\tconst packageDirectory = dirname(manifestPath);\n\tconst entrypointRelativePath = relative(packageDirectory, entrypoint);\n\tif (\n\t\tentrypointRelativePath === \"\" ||\n\t\tentrypointRelativePath === \"..\" ||\n\t\tentrypointRelativePath.startsWith(\"../\") ||\n\t\tentrypointRelativePath.startsWith(\"..\\\\\") ||\n\t\tisAbsolute(entrypointRelativePath)\n\t) {\n\t\tthrow new Error(`Required extension entrypoint is outside its package: ${entrypoint}`);\n\t}\n\tconst manifest = JSON.parse(readFileSync(manifestPath, \"utf8\")) as PackageManifest;\n\tif (manifest.name !== identity.required.name || manifest.version !== identity.required.version) {\n\t\tthrow new Error(\n\t\t\t`Required extension mismatch: expected ${identity.required.name}@${identity.required.version}, found ${manifest.name ?? \"unknown\"}@${manifest.version ?? \"unknown\"}.`,\n\t\t);\n\t}\n\tconst digest = digestArtifact(dirname(entrypoint));\n\tif (digest !== identity.artifact.digest) {\n\t\tthrow new Error(\n\t\t\t`Required extension authenticity check failed for ${identity.required.name}@${identity.required.version}.`,\n\t\t);\n\t}\n}\n\nfunction assertRequiredExtensionExports(value: unknown): asserts value is RequiredExtensionModule {\n\tif (typeof value !== \"object\" || value === null) {\n\t\tthrow new Error(`Required extension ${requiredExtension.name}@${requiredExtension.version} is invalid.`);\n\t}\n\tconst module = value as Record<string, unknown>;\n\tif (\n\t\ttypeof module.createSpAgentExtension !== \"function\" ||\n\t\ttypeof module.handleSpCommand !== \"function\" ||\n\t\ttypeof module.readSpGatewayApiKey !== \"function\" ||\n\t\ttypeof module.readSpGatewayState !== \"function\" ||\n\t\ttypeof module.SP_GATEWAY_PROVIDER_ID !== \"string\"\n\t) {\n\t\tthrow new Error(`Required extension ${requiredExtension.name}@${requiredExtension.version} is invalid.`);\n\t}\n}\n\nlet requiredExtensionPromise: Promise<RequiredExtensionModule> | undefined;\n\nexport async function loadRequiredExtension(options: RequiredExtensionLoadOptions = {}) {\n\tconst usesDefaultLoader = Object.keys(options).length === 0;\n\tif (usesDefaultLoader && requiredExtensionPromise) return requiredExtensionPromise;\n\n\tassertRequiredExtensionIdentity(options);\n\tconst compiled = options.compiled ?? isCompiledExecutable();\n\tconst specifier = compiled\n\t\t? EMBEDDED_REQUIRED_EXTENSION_IDENTITY.required.name\n\t\t: (options.resolvedEntrypoint ?? import.meta.resolve(EMBEDDED_REQUIRED_EXTENSION_IDENTITY.required.name));\n\tconst load = async () => {\n\t\tconst imported = options.importExtension\n\t\t\t? await options.importExtension(specifier)\n\t\t\t: compiled\n\t\t\t\t? await import(\"@senpiper/sp-agent-extensions\")\n\t\t\t\t: await import(specifier);\n\t\tassertRequiredExtensionExports(imported);\n\t\treturn imported;\n\t};\n\tconst promise = load();\n\tif (usesDefaultLoader) requiredExtensionPromise = promise;\n\treturn promise;\n}\n\nexport function createSpModelProviderPolicy(extension: RequiredExtensionModule): ModelProviderPolicy {\n\tconst configured = extension.readSpGatewayState() !== undefined;\n\tif (configured) extension.readSpGatewayApiKey();\n\treturn {\n\t\tallowedProviderIds: [extension.SP_GATEWAY_PROVIDER_ID],\n\t\trequiredProviderIds: configured ? [extension.SP_GATEWAY_PROVIDER_ID] : [],\n\t\tallowModelConfiguration: false,\n\t\tproviderOwners: { [extension.SP_GATEWAY_PROVIDER_ID]: REQUIRED_EXTENSION_OWNER },\n\t};\n}\n\nexport function createSpExtensionRunnerOptions(extensions: readonly Extension[]): ExtensionRunnerOptions {\n\tconst owner = extensions.find((extension) => extension.path === REQUIRED_EXTENSION_OWNER);\n\tif (!owner) throw new Error(\"Required Senpiper Workbench extension did not load.\");\n\treturn {\n\t\tcommandOwnership: {\n\t\t\treservedCommandNames: [\"login\", \"web\"],\n\t\t\towners: new Map([\n\t\t\t\t[\"login\", owner],\n\t\t\t\t[\"web\", owner],\n\t\t\t]),\n\t\t},\n\t\tresourceOwnership: {\n\t\t\ttoolOwners: new Map([[\"ask_user_question\", owner]]),\n\t\t},\n\t};\n}\n\nexport async function createSpMainOptions(): Promise<MainOptions> {\n\tconst extension = await loadRequiredExtension();\n\tconst sessions = await createSpSessionManager();\n\treturn {\n\t\tsessionWriterLeaseProvider: spWriterLeases,\n\t\tonSessionHistoryRoot: (root, customSessionDir) => sessions.setHistoryRoot(root, customSessionDir),\n\t\tonSessionRuntime: (runtime) => sessions.attachRuntime(runtime),\n\t\textensionFactories: [\n\t\t\t{\n\t\t\t\tname: \"sp-agent\",\n\t\t\t\tfactory: extension.createSpAgentExtension({\n\t\t\t\t\tsessions,\n\t\t\t\t\twriterLeaseVersion: 1,\n\t\t\t\t\tonReady: (bridge) => sessions.trackBridge(bridge),\n\t\t\t\t}),\n\t\t\t},\n\t\t],\n\t\tincludeBuiltInExtensions: false,\n\t\tmodelProviderPolicy: createSpModelProviderPolicy(extension),\n\t\textensionRunnerOptionsResolver: createSpExtensionRunnerOptions,\n\t};\n}\n\nexport const requiredExtension = {\n\tname: EMBEDDED_REQUIRED_EXTENSION_IDENTITY.required.name,\n\tversion: EMBEDDED_REQUIRED_EXTENSION_IDENTITY.required.version,\n\tdigest: EMBEDDED_REQUIRED_EXTENSION_IDENTITY.artifact.digest,\n} as const;\n"]}
@@ -144,7 +144,7 @@ export function createSpModelProviderPolicy(extension) {
144
144
  export function createSpExtensionRunnerOptions(extensions) {
145
145
  const owner = extensions.find((extension) => extension.path === REQUIRED_EXTENSION_OWNER);
146
146
  if (!owner)
147
- throw new Error("Required SP extension did not load.");
147
+ throw new Error("Required Senpiper Workbench extension did not load.");
148
148
  return {
149
149
  commandOwnership: {
150
150
  reservedCommandNames: ["login", "web"],
@@ -1 +1 @@
1
- {"version":3,"file":"distribution.js","sourceRoot":"","sources":["../src/distribution.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, join, parse, relative } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type {\n\tExtension,\n\tExtensionFactory,\n\tExtensionRunnerOptions,\n\tMainOptions,\n\tModelProviderPolicy,\n} from \"@senpiper/pi-coding-agent\";\nimport type { TerminalWebBridgeOptions } from \"@senpiper/sp-agent-extensions\";\nimport { EMBEDDED_REQUIRED_EXTENSION_IDENTITY } from \"./extension-identity.generated.ts\";\nimport { createSpSessionManager } from \"./sdk.ts\";\nimport { spWriterLeases } from \"./writer-leases.ts\";\n\nexport { configureSpEnvironment } from \"./environment.ts\";\nexport { SP_AGENT_VERSION } from \"./version.ts\";\n\ndeclare const SP_AGENT_COMPILED: boolean;\n\nexport const REQUIRED_EXTENSION_OWNER = \"<inline:sp-agent>\";\n\ninterface PackageManifest {\n\tname?: string;\n\tversion?: string;\n}\n\ninterface EmbeddedExtensionIdentity {\n\trequired: { name: string; version: string };\n\tartifact: { name: string; version: string; digest: string };\n}\n\nexport interface RequiredExtensionModule {\n\tcreateSpAgentExtension: (options?: TerminalWebBridgeOptions) => ExtensionFactory;\n\thandleSpCommand: (args: string[]) => Promise<boolean>;\n\treadSpGatewayApiKey: () => unknown;\n\treadSpGatewayState: () => unknown;\n\tSP_GATEWAY_PROVIDER_ID: string;\n}\n\ninterface RequiredExtensionValidationOptions {\n\tcompiled?: boolean;\n\tembeddedIdentity?: EmbeddedExtensionIdentity;\n\tresolvedEntrypoint?: string;\n}\n\ninterface RequiredExtensionLoadOptions extends RequiredExtensionValidationOptions {\n\timportExtension?: (specifier: string) => Promise<unknown>;\n}\n\nfunction findPackageManifest(entrypoint: string) {\n\tlet directory = dirname(entrypoint);\n\tconst root = parse(directory).root;\n\twhile (directory !== root) {\n\t\tconst manifestPath = join(directory, \"package.json\");\n\t\tif (existsSync(manifestPath)) return manifestPath;\n\t\tdirectory = dirname(directory);\n\t}\n\treturn undefined;\n}\n\nfunction collectJavaScriptFiles(directory: string): string[] {\n\tconst files: string[] = [];\n\tfor (const entry of readdirSync(directory, { withFileTypes: true })) {\n\t\tconst path = join(directory, entry.name);\n\t\tif (entry.isDirectory()) files.push(...collectJavaScriptFiles(path));\n\t\telse if (entry.isFile() && entry.name.endsWith(\".js\")) files.push(path);\n\t}\n\treturn files.sort((left, right) => relative(directory, left).localeCompare(relative(directory, right)));\n}\n\nfunction digestArtifact(directory: string) {\n\tconst files = collectJavaScriptFiles(directory);\n\tif (files.length === 0) throw new Error(`Required extension artifact contains no JavaScript: ${directory}`);\n\tconst hash = createHash(\"sha256\");\n\tfor (const path of files) {\n\t\tconst artifactPath = relative(directory, path).replaceAll(\"\\\\\", \"/\");\n\t\tconst content = readFileSync(path);\n\t\thash.update(`${artifactPath}\\0${content.byteLength}\\0`);\n\t\thash.update(content);\n\t}\n\treturn `sha256:${hash.digest(\"hex\")}`;\n}\n\nfunction assertEmbeddedIdentity(identity: EmbeddedExtensionIdentity) {\n\tif (\n\t\tidentity.artifact.name !== identity.required.name ||\n\t\tidentity.artifact.version !== identity.required.version ||\n\t\t!/^sha256:[0-9a-f]{64}$/u.test(identity.artifact.digest)\n\t) {\n\t\tthrow new Error(\n\t\t\t`Required extension build identity mismatch: expected ${identity.required.name}@${identity.required.version}.`,\n\t\t);\n\t}\n}\n\nfunction isCompiledExecutable() {\n\treturn typeof SP_AGENT_COMPILED !== \"undefined\" && SP_AGENT_COMPILED;\n}\n\nexport function assertRequiredExtensionIdentity(options: RequiredExtensionValidationOptions = {}) {\n\tconst identity = options.embeddedIdentity ?? EMBEDDED_REQUIRED_EXTENSION_IDENTITY;\n\tassertEmbeddedIdentity(identity);\n\tif (options.compiled ?? isCompiledExecutable()) return;\n\n\tconst resolved = options.resolvedEntrypoint ?? import.meta.resolve(identity.required.name);\n\tif (!resolved.startsWith(\"file:\")) {\n\t\tthrow new Error(`Cannot verify required extension ${identity.required.name}: ${resolved}`);\n\t}\n\tconst entrypoint = fileURLToPath(resolved);\n\tconst manifestPath = findPackageManifest(entrypoint);\n\tif (!manifestPath) {\n\t\tthrow new Error(`Cannot find the manifest for required extension ${identity.required.name}.`);\n\t}\n\tconst packageDirectory = dirname(manifestPath);\n\tconst entrypointRelativePath = relative(packageDirectory, entrypoint);\n\tif (\n\t\tentrypointRelativePath === \"\" ||\n\t\tentrypointRelativePath === \"..\" ||\n\t\tentrypointRelativePath.startsWith(\"../\") ||\n\t\tentrypointRelativePath.startsWith(\"..\\\\\") ||\n\t\tisAbsolute(entrypointRelativePath)\n\t) {\n\t\tthrow new Error(`Required extension entrypoint is outside its package: ${entrypoint}`);\n\t}\n\tconst manifest = JSON.parse(readFileSync(manifestPath, \"utf8\")) as PackageManifest;\n\tif (manifest.name !== identity.required.name || manifest.version !== identity.required.version) {\n\t\tthrow new Error(\n\t\t\t`Required extension mismatch: expected ${identity.required.name}@${identity.required.version}, found ${manifest.name ?? \"unknown\"}@${manifest.version ?? \"unknown\"}.`,\n\t\t);\n\t}\n\tconst digest = digestArtifact(dirname(entrypoint));\n\tif (digest !== identity.artifact.digest) {\n\t\tthrow new Error(\n\t\t\t`Required extension authenticity check failed for ${identity.required.name}@${identity.required.version}.`,\n\t\t);\n\t}\n}\n\nfunction assertRequiredExtensionExports(value: unknown): asserts value is RequiredExtensionModule {\n\tif (typeof value !== \"object\" || value === null) {\n\t\tthrow new Error(`Required extension ${requiredExtension.name}@${requiredExtension.version} is invalid.`);\n\t}\n\tconst module = value as Record<string, unknown>;\n\tif (\n\t\ttypeof module.createSpAgentExtension !== \"function\" ||\n\t\ttypeof module.handleSpCommand !== \"function\" ||\n\t\ttypeof module.readSpGatewayApiKey !== \"function\" ||\n\t\ttypeof module.readSpGatewayState !== \"function\" ||\n\t\ttypeof module.SP_GATEWAY_PROVIDER_ID !== \"string\"\n\t) {\n\t\tthrow new Error(`Required extension ${requiredExtension.name}@${requiredExtension.version} is invalid.`);\n\t}\n}\n\nlet requiredExtensionPromise: Promise<RequiredExtensionModule> | undefined;\n\nexport async function loadRequiredExtension(options: RequiredExtensionLoadOptions = {}) {\n\tconst usesDefaultLoader = Object.keys(options).length === 0;\n\tif (usesDefaultLoader && requiredExtensionPromise) return requiredExtensionPromise;\n\n\tassertRequiredExtensionIdentity(options);\n\tconst compiled = options.compiled ?? isCompiledExecutable();\n\tconst specifier = compiled\n\t\t? EMBEDDED_REQUIRED_EXTENSION_IDENTITY.required.name\n\t\t: (options.resolvedEntrypoint ?? import.meta.resolve(EMBEDDED_REQUIRED_EXTENSION_IDENTITY.required.name));\n\tconst load = async () => {\n\t\tconst imported = options.importExtension\n\t\t\t? await options.importExtension(specifier)\n\t\t\t: compiled\n\t\t\t\t? await import(\"@senpiper/sp-agent-extensions\")\n\t\t\t\t: await import(specifier);\n\t\tassertRequiredExtensionExports(imported);\n\t\treturn imported;\n\t};\n\tconst promise = load();\n\tif (usesDefaultLoader) requiredExtensionPromise = promise;\n\treturn promise;\n}\n\nexport function createSpModelProviderPolicy(extension: RequiredExtensionModule): ModelProviderPolicy {\n\tconst configured = extension.readSpGatewayState() !== undefined;\n\tif (configured) extension.readSpGatewayApiKey();\n\treturn {\n\t\tallowedProviderIds: [extension.SP_GATEWAY_PROVIDER_ID],\n\t\trequiredProviderIds: configured ? [extension.SP_GATEWAY_PROVIDER_ID] : [],\n\t\tallowModelConfiguration: false,\n\t\tproviderOwners: { [extension.SP_GATEWAY_PROVIDER_ID]: REQUIRED_EXTENSION_OWNER },\n\t};\n}\n\nexport function createSpExtensionRunnerOptions(extensions: readonly Extension[]): ExtensionRunnerOptions {\n\tconst owner = extensions.find((extension) => extension.path === REQUIRED_EXTENSION_OWNER);\n\tif (!owner) throw new Error(\"Required SP extension did not load.\");\n\treturn {\n\t\tcommandOwnership: {\n\t\t\treservedCommandNames: [\"login\", \"web\"],\n\t\t\towners: new Map([\n\t\t\t\t[\"login\", owner],\n\t\t\t\t[\"web\", owner],\n\t\t\t]),\n\t\t},\n\t\tresourceOwnership: {\n\t\t\ttoolOwners: new Map([[\"ask_user_question\", owner]]),\n\t\t},\n\t};\n}\n\nexport async function createSpMainOptions(): Promise<MainOptions> {\n\tconst extension = await loadRequiredExtension();\n\tconst sessions = await createSpSessionManager();\n\treturn {\n\t\tsessionWriterLeaseProvider: spWriterLeases,\n\t\tonSessionHistoryRoot: (root, customSessionDir) => sessions.setHistoryRoot(root, customSessionDir),\n\t\tonSessionRuntime: (runtime) => sessions.attachRuntime(runtime),\n\t\textensionFactories: [\n\t\t\t{\n\t\t\t\tname: \"sp-agent\",\n\t\t\t\tfactory: extension.createSpAgentExtension({\n\t\t\t\t\tsessions,\n\t\t\t\t\twriterLeaseVersion: 1,\n\t\t\t\t\tonReady: (bridge) => sessions.trackBridge(bridge),\n\t\t\t\t}),\n\t\t\t},\n\t\t],\n\t\tincludeBuiltInExtensions: false,\n\t\tmodelProviderPolicy: createSpModelProviderPolicy(extension),\n\t\textensionRunnerOptionsResolver: createSpExtensionRunnerOptions,\n\t};\n}\n\nexport const requiredExtension = {\n\tname: EMBEDDED_REQUIRED_EXTENSION_IDENTITY.required.name,\n\tversion: EMBEDDED_REQUIRED_EXTENSION_IDENTITY.required.version,\n\tdigest: EMBEDDED_REQUIRED_EXTENSION_IDENTITY.artifact.digest,\n} as const;\n"]}
1
+ {"version":3,"file":"distribution.js","sourceRoot":"","sources":["../src/distribution.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, join, parse, relative } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type {\n\tExtension,\n\tExtensionFactory,\n\tExtensionRunnerOptions,\n\tMainOptions,\n\tModelProviderPolicy,\n} from \"@senpiper/pi-coding-agent\";\nimport type { TerminalWebBridgeOptions } from \"@senpiper/sp-agent-extensions\";\nimport { EMBEDDED_REQUIRED_EXTENSION_IDENTITY } from \"./extension-identity.generated.ts\";\nimport { createSpSessionManager } from \"./sdk.ts\";\nimport { spWriterLeases } from \"./writer-leases.ts\";\n\nexport { configureSpEnvironment } from \"./environment.ts\";\nexport { SP_AGENT_VERSION } from \"./version.ts\";\n\ndeclare const SP_AGENT_COMPILED: boolean;\n\nexport const REQUIRED_EXTENSION_OWNER = \"<inline:sp-agent>\";\n\ninterface PackageManifest {\n\tname?: string;\n\tversion?: string;\n}\n\ninterface EmbeddedExtensionIdentity {\n\trequired: { name: string; version: string };\n\tartifact: { name: string; version: string; digest: string };\n}\n\nexport interface RequiredExtensionModule {\n\tcreateSpAgentExtension: (options?: TerminalWebBridgeOptions) => ExtensionFactory;\n\thandleSpCommand: (args: string[]) => Promise<boolean>;\n\treadSpGatewayApiKey: () => unknown;\n\treadSpGatewayState: () => unknown;\n\tSP_GATEWAY_PROVIDER_ID: string;\n}\n\ninterface RequiredExtensionValidationOptions {\n\tcompiled?: boolean;\n\tembeddedIdentity?: EmbeddedExtensionIdentity;\n\tresolvedEntrypoint?: string;\n}\n\ninterface RequiredExtensionLoadOptions extends RequiredExtensionValidationOptions {\n\timportExtension?: (specifier: string) => Promise<unknown>;\n}\n\nfunction findPackageManifest(entrypoint: string) {\n\tlet directory = dirname(entrypoint);\n\tconst root = parse(directory).root;\n\twhile (directory !== root) {\n\t\tconst manifestPath = join(directory, \"package.json\");\n\t\tif (existsSync(manifestPath)) return manifestPath;\n\t\tdirectory = dirname(directory);\n\t}\n\treturn undefined;\n}\n\nfunction collectJavaScriptFiles(directory: string): string[] {\n\tconst files: string[] = [];\n\tfor (const entry of readdirSync(directory, { withFileTypes: true })) {\n\t\tconst path = join(directory, entry.name);\n\t\tif (entry.isDirectory()) files.push(...collectJavaScriptFiles(path));\n\t\telse if (entry.isFile() && entry.name.endsWith(\".js\")) files.push(path);\n\t}\n\treturn files.sort((left, right) => relative(directory, left).localeCompare(relative(directory, right)));\n}\n\nfunction digestArtifact(directory: string) {\n\tconst files = collectJavaScriptFiles(directory);\n\tif (files.length === 0) throw new Error(`Required extension artifact contains no JavaScript: ${directory}`);\n\tconst hash = createHash(\"sha256\");\n\tfor (const path of files) {\n\t\tconst artifactPath = relative(directory, path).replaceAll(\"\\\\\", \"/\");\n\t\tconst content = readFileSync(path);\n\t\thash.update(`${artifactPath}\\0${content.byteLength}\\0`);\n\t\thash.update(content);\n\t}\n\treturn `sha256:${hash.digest(\"hex\")}`;\n}\n\nfunction assertEmbeddedIdentity(identity: EmbeddedExtensionIdentity) {\n\tif (\n\t\tidentity.artifact.name !== identity.required.name ||\n\t\tidentity.artifact.version !== identity.required.version ||\n\t\t!/^sha256:[0-9a-f]{64}$/u.test(identity.artifact.digest)\n\t) {\n\t\tthrow new Error(\n\t\t\t`Required extension build identity mismatch: expected ${identity.required.name}@${identity.required.version}.`,\n\t\t);\n\t}\n}\n\nfunction isCompiledExecutable() {\n\treturn typeof SP_AGENT_COMPILED !== \"undefined\" && SP_AGENT_COMPILED;\n}\n\nexport function assertRequiredExtensionIdentity(options: RequiredExtensionValidationOptions = {}) {\n\tconst identity = options.embeddedIdentity ?? EMBEDDED_REQUIRED_EXTENSION_IDENTITY;\n\tassertEmbeddedIdentity(identity);\n\tif (options.compiled ?? isCompiledExecutable()) return;\n\n\tconst resolved = options.resolvedEntrypoint ?? import.meta.resolve(identity.required.name);\n\tif (!resolved.startsWith(\"file:\")) {\n\t\tthrow new Error(`Cannot verify required extension ${identity.required.name}: ${resolved}`);\n\t}\n\tconst entrypoint = fileURLToPath(resolved);\n\tconst manifestPath = findPackageManifest(entrypoint);\n\tif (!manifestPath) {\n\t\tthrow new Error(`Cannot find the manifest for required extension ${identity.required.name}.`);\n\t}\n\tconst packageDirectory = dirname(manifestPath);\n\tconst entrypointRelativePath = relative(packageDirectory, entrypoint);\n\tif (\n\t\tentrypointRelativePath === \"\" ||\n\t\tentrypointRelativePath === \"..\" ||\n\t\tentrypointRelativePath.startsWith(\"../\") ||\n\t\tentrypointRelativePath.startsWith(\"..\\\\\") ||\n\t\tisAbsolute(entrypointRelativePath)\n\t) {\n\t\tthrow new Error(`Required extension entrypoint is outside its package: ${entrypoint}`);\n\t}\n\tconst manifest = JSON.parse(readFileSync(manifestPath, \"utf8\")) as PackageManifest;\n\tif (manifest.name !== identity.required.name || manifest.version !== identity.required.version) {\n\t\tthrow new Error(\n\t\t\t`Required extension mismatch: expected ${identity.required.name}@${identity.required.version}, found ${manifest.name ?? \"unknown\"}@${manifest.version ?? \"unknown\"}.`,\n\t\t);\n\t}\n\tconst digest = digestArtifact(dirname(entrypoint));\n\tif (digest !== identity.artifact.digest) {\n\t\tthrow new Error(\n\t\t\t`Required extension authenticity check failed for ${identity.required.name}@${identity.required.version}.`,\n\t\t);\n\t}\n}\n\nfunction assertRequiredExtensionExports(value: unknown): asserts value is RequiredExtensionModule {\n\tif (typeof value !== \"object\" || value === null) {\n\t\tthrow new Error(`Required extension ${requiredExtension.name}@${requiredExtension.version} is invalid.`);\n\t}\n\tconst module = value as Record<string, unknown>;\n\tif (\n\t\ttypeof module.createSpAgentExtension !== \"function\" ||\n\t\ttypeof module.handleSpCommand !== \"function\" ||\n\t\ttypeof module.readSpGatewayApiKey !== \"function\" ||\n\t\ttypeof module.readSpGatewayState !== \"function\" ||\n\t\ttypeof module.SP_GATEWAY_PROVIDER_ID !== \"string\"\n\t) {\n\t\tthrow new Error(`Required extension ${requiredExtension.name}@${requiredExtension.version} is invalid.`);\n\t}\n}\n\nlet requiredExtensionPromise: Promise<RequiredExtensionModule> | undefined;\n\nexport async function loadRequiredExtension(options: RequiredExtensionLoadOptions = {}) {\n\tconst usesDefaultLoader = Object.keys(options).length === 0;\n\tif (usesDefaultLoader && requiredExtensionPromise) return requiredExtensionPromise;\n\n\tassertRequiredExtensionIdentity(options);\n\tconst compiled = options.compiled ?? isCompiledExecutable();\n\tconst specifier = compiled\n\t\t? EMBEDDED_REQUIRED_EXTENSION_IDENTITY.required.name\n\t\t: (options.resolvedEntrypoint ?? import.meta.resolve(EMBEDDED_REQUIRED_EXTENSION_IDENTITY.required.name));\n\tconst load = async () => {\n\t\tconst imported = options.importExtension\n\t\t\t? await options.importExtension(specifier)\n\t\t\t: compiled\n\t\t\t\t? await import(\"@senpiper/sp-agent-extensions\")\n\t\t\t\t: await import(specifier);\n\t\tassertRequiredExtensionExports(imported);\n\t\treturn imported;\n\t};\n\tconst promise = load();\n\tif (usesDefaultLoader) requiredExtensionPromise = promise;\n\treturn promise;\n}\n\nexport function createSpModelProviderPolicy(extension: RequiredExtensionModule): ModelProviderPolicy {\n\tconst configured = extension.readSpGatewayState() !== undefined;\n\tif (configured) extension.readSpGatewayApiKey();\n\treturn {\n\t\tallowedProviderIds: [extension.SP_GATEWAY_PROVIDER_ID],\n\t\trequiredProviderIds: configured ? [extension.SP_GATEWAY_PROVIDER_ID] : [],\n\t\tallowModelConfiguration: false,\n\t\tproviderOwners: { [extension.SP_GATEWAY_PROVIDER_ID]: REQUIRED_EXTENSION_OWNER },\n\t};\n}\n\nexport function createSpExtensionRunnerOptions(extensions: readonly Extension[]): ExtensionRunnerOptions {\n\tconst owner = extensions.find((extension) => extension.path === REQUIRED_EXTENSION_OWNER);\n\tif (!owner) throw new Error(\"Required Senpiper Workbench extension did not load.\");\n\treturn {\n\t\tcommandOwnership: {\n\t\t\treservedCommandNames: [\"login\", \"web\"],\n\t\t\towners: new Map([\n\t\t\t\t[\"login\", owner],\n\t\t\t\t[\"web\", owner],\n\t\t\t]),\n\t\t},\n\t\tresourceOwnership: {\n\t\t\ttoolOwners: new Map([[\"ask_user_question\", owner]]),\n\t\t},\n\t};\n}\n\nexport async function createSpMainOptions(): Promise<MainOptions> {\n\tconst extension = await loadRequiredExtension();\n\tconst sessions = await createSpSessionManager();\n\treturn {\n\t\tsessionWriterLeaseProvider: spWriterLeases,\n\t\tonSessionHistoryRoot: (root, customSessionDir) => sessions.setHistoryRoot(root, customSessionDir),\n\t\tonSessionRuntime: (runtime) => sessions.attachRuntime(runtime),\n\t\textensionFactories: [\n\t\t\t{\n\t\t\t\tname: \"sp-agent\",\n\t\t\t\tfactory: extension.createSpAgentExtension({\n\t\t\t\t\tsessions,\n\t\t\t\t\twriterLeaseVersion: 1,\n\t\t\t\t\tonReady: (bridge) => sessions.trackBridge(bridge),\n\t\t\t\t}),\n\t\t\t},\n\t\t],\n\t\tincludeBuiltInExtensions: false,\n\t\tmodelProviderPolicy: createSpModelProviderPolicy(extension),\n\t\textensionRunnerOptionsResolver: createSpExtensionRunnerOptions,\n\t};\n}\n\nexport const requiredExtension = {\n\tname: EMBEDDED_REQUIRED_EXTENSION_IDENTITY.required.name,\n\tversion: EMBEDDED_REQUIRED_EXTENSION_IDENTITY.required.version,\n\tdigest: EMBEDDED_REQUIRED_EXTENSION_IDENTITY.artifact.digest,\n} as const;\n"]}
@@ -1,12 +1,12 @@
1
1
  export declare const EMBEDDED_REQUIRED_EXTENSION_IDENTITY: {
2
2
  readonly required: {
3
3
  readonly name: "@senpiper/sp-agent-extensions";
4
- readonly version: "0.1.4";
4
+ readonly version: "0.1.5";
5
5
  };
6
6
  readonly artifact: {
7
7
  readonly name: "@senpiper/sp-agent-extensions";
8
- readonly version: "0.1.4";
9
- readonly digest: "sha256:f4211efa0ca9b8f37d2fa6b912a52f83bf96eda494c8e3de16cad2c307c4511f";
8
+ readonly version: "0.1.5";
9
+ readonly digest: "sha256:c526026def1e6b4b5bf777b9b90583fef1d18bf0793b99821b653a592b771b48";
10
10
  };
11
11
  };
12
12
  //# sourceMappingURL=extension-identity.generated.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"extension-identity.generated.d.ts","sourceRoot":"","sources":["../src/extension-identity.generated.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,oCAAoC;;;;;;;;;;CAUvC,CAAC","sourcesContent":["// Generated by scripts/generate-sp-extension-identity.mjs. Do not edit.\nexport const EMBEDDED_REQUIRED_EXTENSION_IDENTITY = {\n\trequired: {\n\t\tname: \"@senpiper/sp-agent-extensions\",\n\t\tversion: \"0.1.4\",\n\t},\n\tartifact: {\n\t\tname: \"@senpiper/sp-agent-extensions\",\n\t\tversion: \"0.1.4\",\n\t\tdigest: \"sha256:f4211efa0ca9b8f37d2fa6b912a52f83bf96eda494c8e3de16cad2c307c4511f\",\n\t},\n} as const;\n"]}
1
+ {"version":3,"file":"extension-identity.generated.d.ts","sourceRoot":"","sources":["../src/extension-identity.generated.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,oCAAoC;;;;;;;;;;CAUvC,CAAC","sourcesContent":["// Generated by scripts/generate-sp-extension-identity.mjs. Do not edit.\nexport const EMBEDDED_REQUIRED_EXTENSION_IDENTITY = {\n\trequired: {\n\t\tname: \"@senpiper/sp-agent-extensions\",\n\t\tversion: \"0.1.5\",\n\t},\n\tartifact: {\n\t\tname: \"@senpiper/sp-agent-extensions\",\n\t\tversion: \"0.1.5\",\n\t\tdigest: \"sha256:c526026def1e6b4b5bf777b9b90583fef1d18bf0793b99821b653a592b771b48\",\n\t},\n} as const;\n"]}
@@ -2,12 +2,12 @@
2
2
  export const EMBEDDED_REQUIRED_EXTENSION_IDENTITY = {
3
3
  required: {
4
4
  name: "@senpiper/sp-agent-extensions",
5
- version: "0.1.4",
5
+ version: "0.1.5",
6
6
  },
7
7
  artifact: {
8
8
  name: "@senpiper/sp-agent-extensions",
9
- version: "0.1.4",
10
- digest: "sha256:f4211efa0ca9b8f37d2fa6b912a52f83bf96eda494c8e3de16cad2c307c4511f",
9
+ version: "0.1.5",
10
+ digest: "sha256:c526026def1e6b4b5bf777b9b90583fef1d18bf0793b99821b653a592b771b48",
11
11
  },
12
12
  };
13
13
  //# sourceMappingURL=extension-identity.generated.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"extension-identity.generated.js","sourceRoot":"","sources":["../src/extension-identity.generated.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,MAAM,CAAC,MAAM,oCAAoC,GAAG;IACnD,QAAQ,EAAE;QACT,IAAI,EAAE,+BAA+B;QACrC,OAAO,EAAE,OAAO;KAChB;IACD,QAAQ,EAAE;QACT,IAAI,EAAE,+BAA+B;QACrC,OAAO,EAAE,OAAO;QAChB,MAAM,EAAE,yEAAyE;KACjF;CACQ,CAAC","sourcesContent":["// Generated by scripts/generate-sp-extension-identity.mjs. Do not edit.\nexport const EMBEDDED_REQUIRED_EXTENSION_IDENTITY = {\n\trequired: {\n\t\tname: \"@senpiper/sp-agent-extensions\",\n\t\tversion: \"0.1.4\",\n\t},\n\tartifact: {\n\t\tname: \"@senpiper/sp-agent-extensions\",\n\t\tversion: \"0.1.4\",\n\t\tdigest: \"sha256:f4211efa0ca9b8f37d2fa6b912a52f83bf96eda494c8e3de16cad2c307c4511f\",\n\t},\n} as const;\n"]}
1
+ {"version":3,"file":"extension-identity.generated.js","sourceRoot":"","sources":["../src/extension-identity.generated.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,MAAM,CAAC,MAAM,oCAAoC,GAAG;IACnD,QAAQ,EAAE;QACT,IAAI,EAAE,+BAA+B;QACrC,OAAO,EAAE,OAAO;KAChB;IACD,QAAQ,EAAE;QACT,IAAI,EAAE,+BAA+B;QACrC,OAAO,EAAE,OAAO;QAChB,MAAM,EAAE,yEAAyE;KACjF;CACQ,CAAC","sourcesContent":["// Generated by scripts/generate-sp-extension-identity.mjs. Do not edit.\nexport const EMBEDDED_REQUIRED_EXTENSION_IDENTITY = {\n\trequired: {\n\t\tname: \"@senpiper/sp-agent-extensions\",\n\t\tversion: \"0.1.5\",\n\t},\n\tartifact: {\n\t\tname: \"@senpiper/sp-agent-extensions\",\n\t\tversion: \"0.1.5\",\n\t\tdigest: \"sha256:c526026def1e6b4b5bf777b9b90583fef1d18bf0793b99821b653a592b771b48\",\n\t},\n} as const;\n"]}
@@ -157,17 +157,17 @@ EOF
157
157
 
158
158
  rollback() {
159
159
  need readlink
160
- [ -L "$APP_DIR/current" ] || { echo "No active SP release." >&2; exit 1; }
161
- [ -L "$APP_DIR/previous" ] || { echo "No previous SP release is available." >&2; exit 1; }
160
+ [ -L "$APP_DIR/current" ] || { echo "No active Senpiper Workbench release." >&2; exit 1; }
161
+ [ -L "$APP_DIR/previous" ] || { echo "No previous Senpiper Workbench release is available." >&2; exit 1; }
162
162
  current="$(readlink "$APP_DIR/current")"
163
163
  previous="$(readlink "$APP_DIR/previous")"
164
164
  candidate="$APP_DIR/$previous/sp"
165
- [ -x "$candidate" ] || { echo "Previous SP release is incomplete: $candidate" >&2; exit 1; }
165
+ [ -x "$candidate" ] || { echo "Previous Senpiper Workbench release is incomplete: $candidate" >&2; exit 1; }
166
166
  "$candidate" --health-check >/dev/null
167
167
  switch_pointer current "$previous"
168
168
  switch_pointer previous "$current"
169
169
  install_launcher
170
- echo "Rolled back SP to $previous"
170
+ echo "Rolled back Senpiper Workbench to $previous"
171
171
  }
172
172
 
173
173
  case "$MODE" in
@@ -180,7 +180,7 @@ esac
180
180
  if [ "$DEVELOPMENT_MODE" = "1" ]; then
181
181
  echo "Set SP_RELEASE_API_URL for explicit local-development installation." >&2
182
182
  else
183
- echo "This SP installer has no build-baked release API URL; refusing caller-controlled trust roots." >&2
183
+ echo "This Senpiper Workbench installer has no build-baked release API URL; refusing caller-controlled trust roots." >&2
184
184
  fi
185
185
  exit 1
186
186
  }
@@ -192,11 +192,11 @@ need find
192
192
  need awk
193
193
  need cut
194
194
  if ! RELEASE_API_ORIGIN="$(url_origin "$RELEASE_API_URL")"; then
195
- echo "The configured SP release API URL is invalid." >&2
195
+ echo "The configured Senpiper Workbench release API URL is invalid." >&2
196
196
  exit 1
197
197
  fi
198
198
  if [ "$DEVELOPMENT_MODE" != "1" ]; then
199
- case "$RELEASE_API_ORIGIN" in https://*) ;; *) echo "The build-baked SP release API URL must use HTTPS." >&2; exit 1 ;; esac
199
+ case "$RELEASE_API_ORIGIN" in https://*) ;; *) echo "The build-baked Senpiper Workbench release API URL must use HTTPS." >&2; exit 1 ;; esac
200
200
  fi
201
201
  platform="$(detect_platform)"
202
202
  case "$platform" in windows-*) archive_name="sp-$platform.zip" ;; *) archive_name="sp-$platform.tar.gz" ;; esac
@@ -225,7 +225,7 @@ if [ "$ALLOW_UNSIGNED" != "1" ]; then
225
225
  if [ "$DEVELOPMENT_MODE" = "1" ]; then
226
226
  echo "Set SP_RELEASE_PUBLIC_KEY for local-development verification." >&2
227
227
  else
228
- echo "This SP installer has no build-baked Minisign public key." >&2
228
+ echo "This Senpiper Workbench installer has no build-baked Minisign public key." >&2
229
229
  fi
230
230
  exit 1
231
231
  }
@@ -273,4 +273,4 @@ old=""
273
273
  switch_pointer current "releases/$release_name"
274
274
  if [ -n "$old" ] && [ "$old" != "releases/$release_name" ]; then switch_pointer previous "$old"; fi
275
275
  install_launcher
276
- printf 'Activated SP %s (%s)\n' "$tag" "$actual"
276
+ printf 'Activated Senpiper Workbench %s (%s)\n' "$tag" "$actual"
@@ -1 +1 @@
1
- {"version":3,"file":"release-manager.d.ts","sourceRoot":"","sources":["../src/release-manager.ts"],"names":[],"mappings":"AAgCA,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,oBAY1D","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nfunction installerPath() {\n\tconst candidates = [\n\t\tjoin(dirname(process.execPath), \"install-sp.sh\"),\n\t\tjoin(dirname(fileURLToPath(import.meta.url)), \"install-sp.sh\"),\n\t];\n\treturn candidates.find((candidate) => existsSync(candidate));\n}\n\nasync function runInstaller(argument?: \"--repair\" | \"--rollback\") {\n\tconst installer = installerPath();\n\tif (!installer) {\n\t\tthrow new Error(\"SP release installer is unavailable. Reinstall @senpiper/sp-agent from a verified release.\");\n\t}\n\tconst env = { ...process.env };\n\tdelete env.SP_RELEASE_API_URL;\n\tdelete env.SP_RELEASE_PUBLIC_KEY;\n\tdelete env.SP_RELEASE_ALLOW_UNSIGNED;\n\tawait new Promise<void>((resolve, reject) => {\n\t\tconst child = spawn(\"sh\", argument ? [installer, argument] : [installer], { stdio: \"inherit\", env });\n\t\tchild.once(\"error\", reject);\n\t\tchild.once(\"exit\", (code, signal) => {\n\t\t\tif (code === 0) resolve();\n\t\t\telse reject(new Error(`SP installer failed${signal ? ` with signal ${signal}` : ` with exit code ${code}`}.`));\n\t\t});\n\t});\n}\n\nexport async function handleSpReleaseCommand(args: string[]) {\n\tconst [command, ...rest] = args;\n\tif (command !== \"update\" && command !== \"rollback\" && command !== \"repair\") return false;\n\tif (rest.length > 0) {\n\t\tif (rest.length === 1 && (rest[0] === \"--help\" || rest[0] === \"-h\")) {\n\t\t\tconsole.log(`Usage: sp ${command}`);\n\t\t\treturn true;\n\t\t}\n\t\tthrow new Error(`Unknown ${command} option: ${rest[0]}`);\n\t}\n\tawait runInstaller(command === \"rollback\" ? \"--rollback\" : command === \"repair\" ? \"--repair\" : undefined);\n\treturn true;\n}\n"]}
1
+ {"version":3,"file":"release-manager.d.ts","sourceRoot":"","sources":["../src/release-manager.ts"],"names":[],"mappings":"AAuCA,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,oBAY1D","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nfunction installerPath() {\n\tconst candidates = [\n\t\tjoin(dirname(process.execPath), \"install-sp.sh\"),\n\t\tjoin(dirname(fileURLToPath(import.meta.url)), \"install-sp.sh\"),\n\t];\n\treturn candidates.find((candidate) => existsSync(candidate));\n}\n\nasync function runInstaller(argument?: \"--repair\" | \"--rollback\") {\n\tconst installer = installerPath();\n\tif (!installer) {\n\t\tthrow new Error(\n\t\t\t\"Senpiper Workbench release installer is unavailable. Reinstall @senpiper/sp-agent from a verified release.\",\n\t\t);\n\t}\n\tconst env = { ...process.env };\n\tdelete env.SP_RELEASE_API_URL;\n\tdelete env.SP_RELEASE_PUBLIC_KEY;\n\tdelete env.SP_RELEASE_ALLOW_UNSIGNED;\n\tawait new Promise<void>((resolve, reject) => {\n\t\tconst child = spawn(\"sh\", argument ? [installer, argument] : [installer], { stdio: \"inherit\", env });\n\t\tchild.once(\"error\", reject);\n\t\tchild.once(\"exit\", (code, signal) => {\n\t\t\tif (code === 0) resolve();\n\t\t\telse\n\t\t\t\treject(\n\t\t\t\t\tnew Error(\n\t\t\t\t\t\t`Senpiper Workbench installer failed${signal ? ` with signal ${signal}` : ` with exit code ${code}`}.`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t});\n\t});\n}\n\nexport async function handleSpReleaseCommand(args: string[]) {\n\tconst [command, ...rest] = args;\n\tif (command !== \"update\" && command !== \"rollback\" && command !== \"repair\") return false;\n\tif (rest.length > 0) {\n\t\tif (rest.length === 1 && (rest[0] === \"--help\" || rest[0] === \"-h\")) {\n\t\t\tconsole.log(`Usage: sp ${command}`);\n\t\t\treturn true;\n\t\t}\n\t\tthrow new Error(`Unknown ${command} option: ${rest[0]}`);\n\t}\n\tawait runInstaller(command === \"rollback\" ? \"--rollback\" : command === \"repair\" ? \"--repair\" : undefined);\n\treturn true;\n}\n"]}
@@ -12,7 +12,7 @@ function installerPath() {
12
12
  async function runInstaller(argument) {
13
13
  const installer = installerPath();
14
14
  if (!installer) {
15
- throw new Error("SP release installer is unavailable. Reinstall @senpiper/sp-agent from a verified release.");
15
+ throw new Error("Senpiper Workbench release installer is unavailable. Reinstall @senpiper/sp-agent from a verified release.");
16
16
  }
17
17
  const env = { ...process.env };
18
18
  delete env.SP_RELEASE_API_URL;
@@ -25,7 +25,7 @@ async function runInstaller(argument) {
25
25
  if (code === 0)
26
26
  resolve();
27
27
  else
28
- reject(new Error(`SP installer failed${signal ? ` with signal ${signal}` : ` with exit code ${code}`}.`));
28
+ reject(new Error(`Senpiper Workbench installer failed${signal ? ` with signal ${signal}` : ` with exit code ${code}`}.`));
29
29
  });
30
30
  });
31
31
  }
@@ -1 +1 @@
1
- {"version":3,"file":"release-manager.js","sourceRoot":"","sources":["../src/release-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nfunction installerPath() {\n\tconst candidates = [\n\t\tjoin(dirname(process.execPath), \"install-sp.sh\"),\n\t\tjoin(dirname(fileURLToPath(import.meta.url)), \"install-sp.sh\"),\n\t];\n\treturn candidates.find((candidate) => existsSync(candidate));\n}\n\nasync function runInstaller(argument?: \"--repair\" | \"--rollback\") {\n\tconst installer = installerPath();\n\tif (!installer) {\n\t\tthrow new Error(\"SP release installer is unavailable. Reinstall @senpiper/sp-agent from a verified release.\");\n\t}\n\tconst env = { ...process.env };\n\tdelete env.SP_RELEASE_API_URL;\n\tdelete env.SP_RELEASE_PUBLIC_KEY;\n\tdelete env.SP_RELEASE_ALLOW_UNSIGNED;\n\tawait new Promise<void>((resolve, reject) => {\n\t\tconst child = spawn(\"sh\", argument ? [installer, argument] : [installer], { stdio: \"inherit\", env });\n\t\tchild.once(\"error\", reject);\n\t\tchild.once(\"exit\", (code, signal) => {\n\t\t\tif (code === 0) resolve();\n\t\t\telse reject(new Error(`SP installer failed${signal ? ` with signal ${signal}` : ` with exit code ${code}`}.`));\n\t\t});\n\t});\n}\n\nexport async function handleSpReleaseCommand(args: string[]) {\n\tconst [command, ...rest] = args;\n\tif (command !== \"update\" && command !== \"rollback\" && command !== \"repair\") return false;\n\tif (rest.length > 0) {\n\t\tif (rest.length === 1 && (rest[0] === \"--help\" || rest[0] === \"-h\")) {\n\t\t\tconsole.log(`Usage: sp ${command}`);\n\t\t\treturn true;\n\t\t}\n\t\tthrow new Error(`Unknown ${command} option: ${rest[0]}`);\n\t}\n\tawait runInstaller(command === \"rollback\" ? \"--rollback\" : command === \"repair\" ? \"--repair\" : undefined);\n\treturn true;\n}\n"]}
1
+ {"version":3,"file":"release-manager.js","sourceRoot":"","sources":["../src/release-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nfunction installerPath() {\n\tconst candidates = [\n\t\tjoin(dirname(process.execPath), \"install-sp.sh\"),\n\t\tjoin(dirname(fileURLToPath(import.meta.url)), \"install-sp.sh\"),\n\t];\n\treturn candidates.find((candidate) => existsSync(candidate));\n}\n\nasync function runInstaller(argument?: \"--repair\" | \"--rollback\") {\n\tconst installer = installerPath();\n\tif (!installer) {\n\t\tthrow new Error(\n\t\t\t\"Senpiper Workbench release installer is unavailable. Reinstall @senpiper/sp-agent from a verified release.\",\n\t\t);\n\t}\n\tconst env = { ...process.env };\n\tdelete env.SP_RELEASE_API_URL;\n\tdelete env.SP_RELEASE_PUBLIC_KEY;\n\tdelete env.SP_RELEASE_ALLOW_UNSIGNED;\n\tawait new Promise<void>((resolve, reject) => {\n\t\tconst child = spawn(\"sh\", argument ? [installer, argument] : [installer], { stdio: \"inherit\", env });\n\t\tchild.once(\"error\", reject);\n\t\tchild.once(\"exit\", (code, signal) => {\n\t\t\tif (code === 0) resolve();\n\t\t\telse\n\t\t\t\treject(\n\t\t\t\t\tnew Error(\n\t\t\t\t\t\t`Senpiper Workbench installer failed${signal ? ` with signal ${signal}` : ` with exit code ${code}`}.`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t});\n\t});\n}\n\nexport async function handleSpReleaseCommand(args: string[]) {\n\tconst [command, ...rest] = args;\n\tif (command !== \"update\" && command !== \"rollback\" && command !== \"repair\") return false;\n\tif (rest.length > 0) {\n\t\tif (rest.length === 1 && (rest[0] === \"--help\" || rest[0] === \"-h\")) {\n\t\t\tconsole.log(`Usage: sp ${command}`);\n\t\t\treturn true;\n\t\t}\n\t\tthrow new Error(`Unknown ${command} option: ${rest[0]}`);\n\t}\n\tawait runInstaller(command === \"rollback\" ? \"--rollback\" : command === \"repair\" ? \"--repair\" : undefined);\n\treturn true;\n}\n"]}