@stigmer/cli 3.23.1-dev.20260923075205 → 3.25.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/commands/bootstrap.d.ts.map +1 -1
- package/commands/bootstrap.js +16 -57
- package/commands/bootstrap.js.map +1 -1
- package/commands/config/context.d.ts.map +1 -1
- package/commands/config/context.js +41 -5
- package/commands/config/context.js.map +1 -1
- package/commands/up.js +1 -1
- package/commands/up.js.map +1 -1
- package/config/index.d.ts +1 -1
- package/config/index.d.ts.map +1 -1
- package/config/index.js +1 -1
- package/config/index.js.map +1 -1
- package/config/resolve.d.ts +8 -0
- package/config/resolve.d.ts.map +1 -1
- package/config/resolve.js +8 -8
- package/config/resolve.js.map +1 -1
- package/local/bootstrap.d.ts +9 -29
- package/local/bootstrap.d.ts.map +1 -1
- package/local/bootstrap.js +61 -69
- package/local/bootstrap.js.map +1 -1
- package/local/daemon/launch.d.ts +2 -2
- package/local/daemon/launch.d.ts.map +1 -1
- package/marketplace/official.d.ts.map +1 -1
- package/marketplace/official.js +6 -5
- package/marketplace/official.js.map +1 -1
- package/marketplace/render.d.ts.map +1 -1
- package/marketplace/render.js +0 -3
- package/marketplace/render.js.map +1 -1
- package/package.json +7 -7
- package/src/client/client.test.ts +8 -8
- package/src/commands/bootstrap.test.ts +19 -75
- package/src/commands/bootstrap.ts +19 -68
- package/src/commands/config/context.test.ts +171 -0
- package/src/commands/config/context.ts +50 -5
- package/src/commands/marketplace.test.ts +2 -2
- package/src/commands/up.ts +1 -1
- package/src/config/index.ts +1 -0
- package/src/config/resolve.test.ts +2 -2
- package/src/config/resolve.ts +8 -8
- package/src/local/bootstrap.test.ts +132 -65
- package/src/local/bootstrap.ts +64 -139
- package/src/local/daemon/launch.ts +2 -2
- package/src/marketplace/official.ts +6 -5
- package/src/marketplace/read.test.ts +2 -3
- package/src/marketplace/render.ts +0 -3
- package/local/plugins/defaults.d.ts +0 -55
- package/local/plugins/defaults.d.ts.map +0 -1
- package/local/plugins/defaults.js +0 -111
- package/local/plugins/defaults.js.map +0 -1
- package/local/system-org.d.ts +0 -15
- package/local/system-org.d.ts.map +0 -1
- package/local/system-org.js +0 -57
- package/local/system-org.js.map +0 -1
- package/src/local/plugins/defaults.test.ts +0 -271
- package/src/local/plugins/defaults.ts +0 -179
- package/src/local/system-org.test.ts +0 -124
- package/src/local/system-org.ts +0 -63
package/marketplace/official.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// Resolution and on-demand acquisition of the official marketplace.
|
|
2
2
|
//
|
|
3
3
|
// The official catalogue (`plugins/` in the OSS repository, published as
|
|
4
|
-
// `@stigmer/plugins`) is
|
|
5
|
-
// so it follows the server's and the runner's rule:
|
|
6
|
-
// version, so the plugins
|
|
7
|
-
//
|
|
8
|
-
//
|
|
4
|
+
// `@stigmer/plugins`) is what `stigmer install <name>` reads when no other
|
|
5
|
+
// marketplace is named, so it follows the server's and the runner's rule:
|
|
6
|
+
// acquired at the CLI's OWN version, so the plugins it installs match the
|
|
7
|
+
// control plane that serves them. A lean `npx @stigmer/cli` does not carry the
|
|
8
|
+
// content; it is fetched once, the first time an install needs it, into
|
|
9
|
+
// ~/.stigmer/runtimes/<version>/ like the server and the runner.
|
|
9
10
|
//
|
|
10
11
|
// Two sources, tried in order (mirrors runtime/server.ts and runtime/runner.ts):
|
|
11
12
|
// 1. A repo-tree checkout (dev): `<repo>/plugins`, the tree itself.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"official.js","sourceRoot":"","sources":["../../src/marketplace/official.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,EAAE;AACF,yEAAyE;AACzE,
|
|
1
|
+
{"version":3,"file":"official.js","sourceRoot":"","sources":["../../src/marketplace/official.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/marketplace/render.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EAExB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,KAAK,mBAAmB,EAAkB,MAAM,WAAW,CAAC;AAErE,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,kBAAkB,GAC1B,aAAa,CA6Bf;AAED,oFAAoF;AACpF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,qGAAqG;IACrG,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,mBAAmB,GAAG,UAAU,EAAE,CAyBtE;AAED,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,gBAAgB,EAC7B,IAAI,EAAE,mBAAmB,EACzB,OAAO,EAAE,SAAS,UAAU,EAAE,GAC7B,aAAa,
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/marketplace/render.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EAExB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,KAAK,mBAAmB,EAAkB,MAAM,WAAW,CAAC;AAErE,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,kBAAkB,GAC1B,aAAa,CA6Bf;AAED,oFAAoF;AACpF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,qGAAqG;IACrG,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,mBAAmB,GAAG,UAAU,EAAE,CAyBtE;AAED,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,gBAAgB,EAC7B,IAAI,EAAE,mBAAmB,EACzB,OAAO,EAAE,SAAS,UAAU,EAAE,GAC7B,aAAa,CAsDf"}
|
package/marketplace/render.js
CHANGED
|
@@ -79,8 +79,6 @@ export function renderMarketplaceShow(marketplace, tree, entries) {
|
|
|
79
79
|
if (tree.marketplace.owner?.name !== undefined)
|
|
80
80
|
about.field("Owner", tree.marketplace.owner.name);
|
|
81
81
|
about.field("Format", tree.marketplace.path);
|
|
82
|
-
if (tree.marketplace.defaults.length > 0)
|
|
83
|
-
about.field("Defaults", tree.marketplace.defaults.join(", "));
|
|
84
82
|
const plugins = result.addSection("Plugins");
|
|
85
83
|
for (const entry of entries) {
|
|
86
84
|
const version = entry.version === undefined ? "" : `@${entry.version}`;
|
|
@@ -109,7 +107,6 @@ export function renderMarketplaceShow(marketplace, tree, entries) {
|
|
|
109
107
|
...(tree.marketplace.owner !== undefined && {
|
|
110
108
|
owner: tree.marketplace.owner,
|
|
111
109
|
}),
|
|
112
|
-
defaults: tree.marketplace.defaults,
|
|
113
110
|
},
|
|
114
111
|
plugins: entries,
|
|
115
112
|
warnings: tree.warnings,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/marketplace/render.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,2EAA2E;AAC3E,sEAAsE;AACtE,yEAAyE;AACzE,0EAA0E;AAE1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAGL,cAAc,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EAA4B,cAAc,EAAE,MAAM,WAAW,CAAC;AAErE,MAAM,UAAU,qBAAqB,CACnC,OAA2B;IAE3B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC;IAC/D,MAAM,MAAM,GACV,OAAO,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC;QAC7B,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC;QAC1D,CAAC,CAAC,aAAa,CAAC,OAAO,CACnB,GAAG,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,WAAW,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,uBAAuB,CACrG,CAAC;IACR,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAC7C,KAAK,MAAM,WAAW,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACxC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,cAAc,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;IACtE,CAAC;IACD,KAAK,MAAM,WAAW,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QAC7C,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,mBAAmB,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAC;IAC1E,MAAM,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC;IAC7E,OAAO,MAAM,CAAC,QAAQ,CAAC;QACrB,YAAY,EAAE;YACZ,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;gBACrC,IAAI,EAAE,WAAW,CAAC,IAAI;gBACtB,MAAM,EAAE,WAAW,CAAC,MAAM;aAC3B,CAAC,CAAC;YACH,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;gBAC1C,IAAI,EAAE,WAAW,CAAC,IAAI;gBACtB,UAAU,EAAE,WAAW,CAAC,MAAM;aAC/B,CAAC,CAAC;SACJ;KACF,CAAC,CAAC;AACL,CAAC;AAYD;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,IAAyB;IACtD,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAC5C,MAAM,OAAO,GAAG,iBAAiB,CAC/B,mBAAmB,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CACvD,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;YAChB,OAAO;gBACL,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,IAAI;oBACrC,WAAW,EAAE,KAAK,CAAC,WAAW;iBAC/B,CAAC;gBACF,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM;aAChC,CAAC;QACJ,CAAC;QACD,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,CAAC;QACpE,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,IAAI;gBAC1C,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO;aAChC,CAAC;YACF,GAAG,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,CAAC;SAClD,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,WAA6B,EAC7B,IAAyB,EACzB,OAA8B;IAE9B,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAChC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,CACxC,CAAC,MAAM,CAAC;IACT,MAAM,QAAQ,GAAG,gBAAgB,WAAW,CAAC,IAAI,YAAY,KAAK,CAAC,WAAW,EAAE,QAAQ,CAAC,EAAE,CAAC;IAC5F,MAAM,MAAM,GACV,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,KAAK,OAAO,CAAC,MAAM;QAC1D,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC;QACjC,CAAC,CAAC,aAAa,CAAC,OAAO,CACnB,GAAG,QAAQ,UAAU,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,WAAW,CAAC,EAAE,SAAS,CAAC,EAAE,CAC/F,CAAC;IAER,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAC/C,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAC3C,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,cAAc,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1D,IAAI,IAAI,CAAC,WAAW,CAAC,WAAW,KAAK,SAAS;QAC5C,KAAK,CAAC,KAAK,CAAC,aAAa,EAAE,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;IAC3D,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,KAAK,SAAS;QAC5C,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACpD,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/marketplace/render.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stigmer/cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.25.0",
|
|
4
4
|
"description": "Stigmer command-line interface — manage agents, workflows, MCP servers, skills, and executions from the terminal",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -35,12 +35,12 @@
|
|
|
35
35
|
"@connectrpc/connect": "^2.0.0",
|
|
36
36
|
"@connectrpc/connect-node": "^2.1.1",
|
|
37
37
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
38
|
-
"@stigmer/ink": "3.
|
|
39
|
-
"@stigmer/mcp-server": "3.
|
|
40
|
-
"@stigmer/plugin-package": "3.
|
|
41
|
-
"@stigmer/protos": "3.
|
|
42
|
-
"@stigmer/sdk": "3.
|
|
43
|
-
"@stigmer/zip-structure": "3.
|
|
38
|
+
"@stigmer/ink": "3.25.0",
|
|
39
|
+
"@stigmer/mcp-server": "3.25.0",
|
|
40
|
+
"@stigmer/plugin-package": "3.25.0",
|
|
41
|
+
"@stigmer/protos": "3.25.0",
|
|
42
|
+
"@stigmer/sdk": "3.25.0",
|
|
43
|
+
"@stigmer/zip-structure": "3.25.0",
|
|
44
44
|
"commander": "^12.1.0",
|
|
45
45
|
"fflate": "^0.8.3",
|
|
46
46
|
"ink": "^7.0.0",
|
|
@@ -94,9 +94,9 @@ describe("BackendClient — the server's edition and what it serves (20260911.11
|
|
|
94
94
|
config: cloud("t"),
|
|
95
95
|
transport: oss.transport,
|
|
96
96
|
});
|
|
97
|
-
expect(
|
|
98
|
-
|
|
99
|
-
)
|
|
97
|
+
expect(await client.isResourceAvailable(ApiResourceKind.subscription)).toBe(
|
|
98
|
+
false,
|
|
99
|
+
);
|
|
100
100
|
expect(await client.isResourceAvailable(ApiResourceKind.agent)).toBe(true);
|
|
101
101
|
|
|
102
102
|
const cloudServer = serverAnswering(ServerEdition.cloud);
|
|
@@ -105,7 +105,7 @@ describe("BackendClient — the server's edition and what it serves (20260911.11
|
|
|
105
105
|
transport: cloudServer.transport,
|
|
106
106
|
});
|
|
107
107
|
expect(
|
|
108
|
-
await onCloud.isResourceAvailable(ApiResourceKind.
|
|
108
|
+
await onCloud.isResourceAvailable(ApiResourceKind.subscription),
|
|
109
109
|
).toBe(true);
|
|
110
110
|
});
|
|
111
111
|
|
|
@@ -117,7 +117,7 @@ describe("BackendClient — the server's edition and what it serves (20260911.11
|
|
|
117
117
|
});
|
|
118
118
|
await client.connect();
|
|
119
119
|
await client.isResourceAvailable(ApiResourceKind.agent);
|
|
120
|
-
await client.isResourceAvailable(ApiResourceKind.
|
|
120
|
+
await client.isResourceAvailable(ApiResourceKind.subscription);
|
|
121
121
|
const info = await client.serverInfo();
|
|
122
122
|
expect(info.deploymentMode).toBe("local");
|
|
123
123
|
expect(info.version).toBe("1.2.3");
|
|
@@ -134,9 +134,9 @@ describe("BackendClient — the server's edition and what it serves (20260911.11
|
|
|
134
134
|
transport: server.transport,
|
|
135
135
|
});
|
|
136
136
|
await expect(client.serverInfo()).rejects.toThrow("server warming up");
|
|
137
|
-
expect(
|
|
138
|
-
|
|
139
|
-
)
|
|
137
|
+
expect(await client.isResourceAvailable(ApiResourceKind.subscription)).toBe(
|
|
138
|
+
true,
|
|
139
|
+
);
|
|
140
140
|
expect(server.asked(), "the rejection was not cached").toBe(2);
|
|
141
141
|
});
|
|
142
142
|
});
|
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
// Command-level contract for `stigmer bootstrap`: against the configured
|
|
2
|
-
// backend it ensures the
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
// the function level (local/bootstrap.test.ts), where a synthetic list can
|
|
9
|
-
// stage it. A real Connect backend over h2c serves the org and plugin
|
|
10
|
-
// controllers; the config file (HOME redirected) points a selfhost backend
|
|
11
|
-
// at it.
|
|
2
|
+
// backend it ensures the organization the CLI falls back to (`stigmer`) and
|
|
3
|
+
// installs nothing, so the command creates the organization and renders one
|
|
4
|
+
// Organization section; a second run over a ready backend reports the org
|
|
5
|
+
// present and creates nothing. A real Connect backend over h2c serves the org
|
|
6
|
+
// controllers; the config file (HOME redirected) points a selfhost backend at
|
|
7
|
+
// it.
|
|
12
8
|
|
|
13
|
-
import { createHash } from "node:crypto";
|
|
14
9
|
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
15
10
|
import {
|
|
16
11
|
createServer as createHttp2Server,
|
|
@@ -21,16 +16,8 @@ import type { AddressInfo } from "node:net";
|
|
|
21
16
|
import { tmpdir } from "node:os";
|
|
22
17
|
import { join } from "node:path";
|
|
23
18
|
import { create } from "@bufbuild/protobuf";
|
|
24
|
-
import {
|
|
19
|
+
import type { ConnectRouter } from "@connectrpc/connect";
|
|
25
20
|
import { connectNodeAdapter } from "@connectrpc/connect-node";
|
|
26
|
-
import {
|
|
27
|
-
type Plugin,
|
|
28
|
-
PluginSchema,
|
|
29
|
-
} from "@stigmer/protos/ai/stigmer/agentic/plugin/v1/api_pb";
|
|
30
|
-
import { PluginCommandController } from "@stigmer/protos/ai/stigmer/agentic/plugin/v1/command_pb";
|
|
31
|
-
import { ListPluginMembersResponseSchema } from "@stigmer/protos/ai/stigmer/agentic/plugin/v1/io_pb";
|
|
32
|
-
import { PluginQueryController } from "@stigmer/protos/ai/stigmer/agentic/plugin/v1/query_pb";
|
|
33
|
-
import { PluginState } from "@stigmer/protos/ai/stigmer/agentic/plugin/v1/status_pb";
|
|
34
21
|
import {
|
|
35
22
|
type Organization,
|
|
36
23
|
OrganizationSchema,
|
|
@@ -48,9 +35,8 @@ import {
|
|
|
48
35
|
it,
|
|
49
36
|
vi,
|
|
50
37
|
} from "vitest";
|
|
38
|
+
import { DEFAULT_LOCAL_ORG } from "../config/index.js";
|
|
51
39
|
import { classify, ExitCode } from "../errors/index.js";
|
|
52
|
-
import { prepareDefaultPlugins } from "../local/plugins/defaults.js";
|
|
53
|
-
import { SYSTEM_ORG } from "../local/system-org.js";
|
|
54
40
|
import { buildProgram } from "../program.js";
|
|
55
41
|
|
|
56
42
|
let backend: Http2Server;
|
|
@@ -58,19 +44,12 @@ let port: number;
|
|
|
58
44
|
const openSessions = new Set<ServerHttp2Session>();
|
|
59
45
|
|
|
60
46
|
let orgs: Map<string, Organization>;
|
|
61
|
-
let
|
|
62
|
-
let pushes: number;
|
|
47
|
+
let creates: number;
|
|
63
48
|
|
|
64
49
|
let home: string;
|
|
65
50
|
let originalHome: string | undefined;
|
|
66
51
|
|
|
67
|
-
/** The catalogue's defaults by archive digest: how this backend names what it is sent. */
|
|
68
|
-
let nameByDigest: Map<string, string>;
|
|
69
|
-
|
|
70
52
|
beforeAll(async () => {
|
|
71
|
-
nameByDigest = new Map(
|
|
72
|
-
(await prepareDefaultPlugins()).map((entry) => [entry.push.digest, entry.name]),
|
|
73
|
-
);
|
|
74
53
|
const routes = (router: ConnectRouter) => {
|
|
75
54
|
router.service(OrganizationQueryController, {
|
|
76
55
|
findMyOrganizations: () =>
|
|
@@ -78,40 +57,13 @@ beforeAll(async () => {
|
|
|
78
57
|
});
|
|
79
58
|
router.service(OrganizationCommandController, {
|
|
80
59
|
create: (org) => {
|
|
60
|
+
creates += 1;
|
|
81
61
|
const row = create(OrganizationSchema, org);
|
|
82
62
|
if (row.metadata !== undefined) row.metadata.id = "org_1";
|
|
83
63
|
orgs.set(row.metadata?.slug ?? "", row);
|
|
84
64
|
return row;
|
|
85
65
|
},
|
|
86
66
|
});
|
|
87
|
-
router.service(PluginCommandController, {
|
|
88
|
-
push: (req) => {
|
|
89
|
-
pushes += 1;
|
|
90
|
-
const digest = createHash("sha256").update(req.artifact).digest("hex");
|
|
91
|
-
const slug = nameByDigest.get(digest);
|
|
92
|
-
if (slug === undefined) {
|
|
93
|
-
throw new ConnectError("archive is not a catalogue default", Code.InvalidArgument);
|
|
94
|
-
}
|
|
95
|
-
const row = create(PluginSchema, {
|
|
96
|
-
metadata: { id: `plg_${slug}`, slug, org: req.org, visibility: req.visibility },
|
|
97
|
-
spec: { name: slug },
|
|
98
|
-
status: { digest, state: PluginState.READY },
|
|
99
|
-
});
|
|
100
|
-
plugins.set(slug, row);
|
|
101
|
-
return row;
|
|
102
|
-
},
|
|
103
|
-
});
|
|
104
|
-
router.service(PluginQueryController, {
|
|
105
|
-
getByReference: (ref) => {
|
|
106
|
-
const row = plugins.get(ref.slug);
|
|
107
|
-
if (row === undefined) {
|
|
108
|
-
throw new ConnectError(`plugin ${ref.slug} not found`, Code.NotFound);
|
|
109
|
-
}
|
|
110
|
-
return row;
|
|
111
|
-
},
|
|
112
|
-
listMembers: () =>
|
|
113
|
-
create(ListPluginMembersResponseSchema, { members: [] }),
|
|
114
|
-
});
|
|
115
67
|
};
|
|
116
68
|
backend = createHttp2Server(connectNodeAdapter({ routes }));
|
|
117
69
|
backend.on("session", (session) => {
|
|
@@ -129,8 +81,7 @@ afterAll(async () => {
|
|
|
129
81
|
|
|
130
82
|
beforeEach(() => {
|
|
131
83
|
orgs = new Map();
|
|
132
|
-
|
|
133
|
-
pushes = 0;
|
|
84
|
+
creates = 0;
|
|
134
85
|
originalHome = process.env.HOME;
|
|
135
86
|
home = mkdtempSync(join(tmpdir(), "stigmer-bootstrap-cmd-"));
|
|
136
87
|
process.env.HOME = home;
|
|
@@ -198,37 +149,30 @@ function section(payload: { sections?: JsonSection[] }, title: string) {
|
|
|
198
149
|
}
|
|
199
150
|
|
|
200
151
|
describe("bootstrap", () => {
|
|
201
|
-
it("creates the
|
|
152
|
+
it("creates the organization, installs nothing, and reports it", async () => {
|
|
202
153
|
const outcome = await run("--json");
|
|
203
154
|
expect(outcome.exitCode).toBe(ExitCode.Success);
|
|
204
|
-
expect(orgs.has(
|
|
205
|
-
expect(pushes).toBe(0);
|
|
155
|
+
expect(orgs.has(DEFAULT_LOCAL_ORG)).toBe(true);
|
|
206
156
|
|
|
207
157
|
const payload = JSON.parse(outcome.stdout);
|
|
208
158
|
expect(payload.status).toBe("success");
|
|
209
159
|
expect(payload.message).toBe("Backend is ready");
|
|
210
|
-
expect(
|
|
211
|
-
|
|
160
|
+
expect(payload.sections?.map((s: JsonSection) => s.title)).toEqual(["Organization"]);
|
|
161
|
+
expect(section(payload, "Organization")?.fields).toEqual([
|
|
162
|
+
{ key: "Slug", value: DEFAULT_LOCAL_ORG },
|
|
212
163
|
{ key: "State", value: "created" },
|
|
213
164
|
]);
|
|
214
|
-
expect(section(payload, "Default plugins")?.fields ?? []).toEqual([]);
|
|
215
165
|
});
|
|
216
166
|
|
|
217
|
-
it("is a no-op the second time: org present, nothing
|
|
167
|
+
it("is a no-op the second time: org present, nothing created", async () => {
|
|
218
168
|
await run("--json");
|
|
219
|
-
const pushedFirst = pushes;
|
|
220
169
|
const outcome = await run("--json");
|
|
221
170
|
expect(outcome.exitCode).toBe(ExitCode.Success);
|
|
222
|
-
expect(
|
|
171
|
+
expect(creates).toBe(1);
|
|
223
172
|
const payload = JSON.parse(outcome.stdout);
|
|
224
|
-
expect(section(payload, "
|
|
173
|
+
expect(section(payload, "Organization")?.fields).toContainEqual({
|
|
225
174
|
key: "State",
|
|
226
175
|
value: "present",
|
|
227
176
|
});
|
|
228
|
-
expect(
|
|
229
|
-
(section(payload, "Default plugins")?.fields ?? []).every(
|
|
230
|
-
(f) => f.value === "up-to-date",
|
|
231
|
-
),
|
|
232
|
-
).toBe(true);
|
|
233
177
|
});
|
|
234
178
|
});
|
|
@@ -1,26 +1,17 @@
|
|
|
1
|
-
// `stigmer bootstrap` — make the configured backend
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
1
|
+
// `stigmer bootstrap` — make the configured backend ready for the CLI: the
|
|
2
|
+
// organization it falls back to when none is named (`stigmer`) exists.
|
|
3
|
+
// `stigmer up` does this for the local stack on its own; this verb is for a
|
|
4
|
+
// raw self-hosted server behind docker-compose or Helm, and runs the very
|
|
5
|
+
// same act (local/bootstrap.ts), so "ready" has one meaning everywhere. A
|
|
6
|
+
// team that created its organization in the console points the CLI at that
|
|
7
|
+
// one instead (`stigmer config context set --org`) and needs no bootstrap.
|
|
8
8
|
//
|
|
9
|
-
// Flagless on purpose
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
// The verb never deletes anything; a scheduled lane must be able to run it
|
|
13
|
-
// without that power.
|
|
14
|
-
//
|
|
15
|
-
// Exit is non-zero when any default failed to land, after the outcomes are
|
|
16
|
-
// rendered, so a lane's run is red for the right reason and a human reads
|
|
17
|
-
// what did and did not install. Heavy modules load lazily inside the action
|
|
18
|
-
// so `--help` stays fast.
|
|
9
|
+
// Flagless on purpose: the act is idempotent, so there is nothing to force;
|
|
10
|
+
// a second run changes nothing and says so. It never deletes anything.
|
|
11
|
+
// Heavy modules load lazily inside the action so `--help` stays fast.
|
|
19
12
|
|
|
20
13
|
import type { Command } from "commander";
|
|
21
|
-
import { ensureAuthenticated } from "../config/index.js";
|
|
22
|
-
import { CliExitError } from "../errors/cli-exit-error.js";
|
|
23
|
-
import { ExitCode } from "../errors/exit-codes.js";
|
|
14
|
+
import { DEFAULT_LOCAL_ORG, ensureAuthenticated } from "../config/index.js";
|
|
24
15
|
import { CommandResult, type OutputFlags, renderResult } from "../output/index.js";
|
|
25
16
|
import { addResultFlags, resultFormat } from "./shared.js";
|
|
26
17
|
|
|
@@ -28,64 +19,24 @@ export function registerBootstrap(program: Command): void {
|
|
|
28
19
|
const bootstrap = program
|
|
29
20
|
.command("bootstrap")
|
|
30
21
|
.description(
|
|
31
|
-
"make the configured backend ready: ensure the
|
|
22
|
+
"make the configured backend ready: ensure the organization the CLI uses when none is named",
|
|
32
23
|
)
|
|
33
24
|
.action((options: OutputFlags) => runBootstrapCommand(options));
|
|
34
25
|
addResultFlags(bootstrap);
|
|
35
26
|
}
|
|
36
27
|
|
|
37
28
|
async function runBootstrapCommand(flags: OutputFlags): Promise<void> {
|
|
38
|
-
const [{ connectBackend }, { bootstrapBackend }
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
import("../local/system-org.js"),
|
|
43
|
-
]);
|
|
29
|
+
const [{ connectBackend }, { bootstrapBackend }] = await Promise.all([
|
|
30
|
+
import("../backend.js"),
|
|
31
|
+
import("../local/bootstrap.js"),
|
|
32
|
+
]);
|
|
44
33
|
|
|
45
34
|
const client = connectBackend();
|
|
46
35
|
ensureAuthenticated(client.config);
|
|
47
36
|
|
|
48
|
-
const
|
|
49
|
-
process.stderr.write(`${line}\n`);
|
|
50
|
-
};
|
|
51
|
-
const result = await bootstrapBackend(client.stigmer, say);
|
|
37
|
+
const state = await bootstrapBackend(client.stigmer);
|
|
52
38
|
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
failed.length === 0
|
|
56
|
-
? CommandResult.success("Backend is ready")
|
|
57
|
-
: CommandResult.warning(
|
|
58
|
-
`Backend bootstrapped with ${failed.length} default plugin${failed.length === 1 ? "" : "s"} not installed`,
|
|
59
|
-
);
|
|
60
|
-
out
|
|
61
|
-
.addSection("System organization")
|
|
62
|
-
.field("Slug", SYSTEM_ORG)
|
|
63
|
-
.field("State", result.org);
|
|
64
|
-
const plugins = out.addSection("Default plugins");
|
|
65
|
-
for (const outcome of result.plugins.outcomes) {
|
|
66
|
-
switch (outcome.action) {
|
|
67
|
-
case "installed":
|
|
68
|
-
case "up-to-date":
|
|
69
|
-
plugins.field(outcome.name, outcome.action);
|
|
70
|
-
break;
|
|
71
|
-
case "failed":
|
|
72
|
-
plugins.field(outcome.name, `failed: ${outcome.error}`);
|
|
73
|
-
break;
|
|
74
|
-
default: {
|
|
75
|
-
const exhaustive: never = outcome;
|
|
76
|
-
throw new Error(`unhandled outcome ${String(exhaustive)}`);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
if (failed.length > 0) {
|
|
81
|
-
out.hint("Fix the cause named above and run 'stigmer bootstrap' again.");
|
|
82
|
-
}
|
|
39
|
+
const out = CommandResult.success("Backend is ready");
|
|
40
|
+
out.addSection("Organization").field("Slug", DEFAULT_LOCAL_ORG).field("State", state);
|
|
83
41
|
renderResult(out, resultFormat(flags));
|
|
84
|
-
|
|
85
|
-
if (failed.length > 0) {
|
|
86
|
-
throw new CliExitError(
|
|
87
|
-
`default plugin${failed.length === 1 ? "" : "s"} not installed: ${failed.join(", ")}`,
|
|
88
|
-
ExitCode.General,
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
42
|
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
// Command-level contract for `stigmer config context set --org`: an
|
|
2
|
+
// organization the caller belongs to on the active backend is persisted as
|
|
3
|
+
// the context and then resolved by every command; a slug the backend does not
|
|
4
|
+
// list among the caller's own is refused as not found and the config file is
|
|
5
|
+
// left byte-for-byte as it was; an empty slug clears the context without
|
|
6
|
+
// asking the backend; no `--org` at all is a usage error. And `context show`
|
|
7
|
+
// names the active backend, not the legacy local/cloud switch the file also
|
|
8
|
+
// carries. A real Connect backend over h2c serves findMyOrganizations; the
|
|
9
|
+
// config file (HOME redirected) points a selfhost backend at it.
|
|
10
|
+
|
|
11
|
+
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
12
|
+
import {
|
|
13
|
+
createServer as createHttp2Server,
|
|
14
|
+
type Http2Server,
|
|
15
|
+
type ServerHttp2Session,
|
|
16
|
+
} from "node:http2";
|
|
17
|
+
import type { AddressInfo } from "node:net";
|
|
18
|
+
import { tmpdir } from "node:os";
|
|
19
|
+
import { join } from "node:path";
|
|
20
|
+
import { create } from "@bufbuild/protobuf";
|
|
21
|
+
import type { ConnectRouter } from "@connectrpc/connect";
|
|
22
|
+
import { connectNodeAdapter } from "@connectrpc/connect-node";
|
|
23
|
+
import { OrganizationSchema } from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/api_pb";
|
|
24
|
+
import { OrganizationsSchema } from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/io_pb";
|
|
25
|
+
import { OrganizationQueryController } from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/query_pb";
|
|
26
|
+
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
|
27
|
+
import { load, resolveOrganization } from "../../config/index.js";
|
|
28
|
+
import { classify, ExitCode } from "../../errors/index.js";
|
|
29
|
+
import { buildProgram } from "../../program.js";
|
|
30
|
+
|
|
31
|
+
let backend: Http2Server;
|
|
32
|
+
let port: number;
|
|
33
|
+
const openSessions = new Set<ServerHttp2Session>();
|
|
34
|
+
let lookups: number;
|
|
35
|
+
|
|
36
|
+
let home: string;
|
|
37
|
+
let originalHome: string | undefined;
|
|
38
|
+
|
|
39
|
+
beforeAll(async () => {
|
|
40
|
+
const routes = (router: ConnectRouter) => {
|
|
41
|
+
router.service(OrganizationQueryController, {
|
|
42
|
+
findMyOrganizations: () => {
|
|
43
|
+
lookups += 1;
|
|
44
|
+
return create(OrganizationsSchema, {
|
|
45
|
+
entries: [create(OrganizationSchema, { metadata: { id: "acme", slug: "acme" } })],
|
|
46
|
+
});
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
backend = createHttp2Server(connectNodeAdapter({ routes }));
|
|
51
|
+
backend.on("session", (session) => {
|
|
52
|
+
openSessions.add(session);
|
|
53
|
+
session.on("close", () => openSessions.delete(session));
|
|
54
|
+
});
|
|
55
|
+
await new Promise<void>((resolve) => backend.listen(0, "127.0.0.1", resolve));
|
|
56
|
+
port = (backend.address() as AddressInfo).port;
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
afterAll(async () => {
|
|
60
|
+
for (const session of openSessions) session.destroy();
|
|
61
|
+
await new Promise<void>((resolve) => backend.close(() => resolve()));
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
beforeEach(() => {
|
|
65
|
+
lookups = 0;
|
|
66
|
+
originalHome = process.env.HOME;
|
|
67
|
+
home = mkdtempSync(join(tmpdir(), "stigmer-context-cmd-"));
|
|
68
|
+
process.env.HOME = home;
|
|
69
|
+
mkdirSync(join(home, ".stigmer"), { recursive: true });
|
|
70
|
+
writeFileSync(
|
|
71
|
+
configFile(),
|
|
72
|
+
[
|
|
73
|
+
"backend:",
|
|
74
|
+
" type: cloud",
|
|
75
|
+
"backends:",
|
|
76
|
+
" team:",
|
|
77
|
+
" type: selfhost",
|
|
78
|
+
` endpoint: 127.0.0.1:${port}`,
|
|
79
|
+
"current_backend: team",
|
|
80
|
+
"",
|
|
81
|
+
].join("\n"),
|
|
82
|
+
);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
afterEach(() => {
|
|
86
|
+
if (originalHome === undefined) delete process.env.HOME;
|
|
87
|
+
else process.env.HOME = originalHome;
|
|
88
|
+
rmSync(home, { recursive: true, force: true });
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
function configFile(): string {
|
|
92
|
+
return join(home, ".stigmer", "config.yaml");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
interface RunOutcome {
|
|
96
|
+
readonly exitCode: number;
|
|
97
|
+
readonly message: string;
|
|
98
|
+
readonly stdout: string;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function run(...args: string[]): Promise<RunOutcome> {
|
|
102
|
+
return runContext("set", ...args);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async function runContext(...args: string[]): Promise<RunOutcome> {
|
|
106
|
+
const program = buildProgram();
|
|
107
|
+
program.exitOverride();
|
|
108
|
+
let stdout = "";
|
|
109
|
+
const outSpy = vi.spyOn(process.stdout, "write").mockImplementation((chunk) => {
|
|
110
|
+
stdout += String(chunk);
|
|
111
|
+
return true;
|
|
112
|
+
});
|
|
113
|
+
const errSpy = vi.spyOn(process.stderr, "write").mockReturnValue(true);
|
|
114
|
+
try {
|
|
115
|
+
await program.parseAsync(["node", "stigmer", "config", "context", ...args]);
|
|
116
|
+
return { exitCode: ExitCode.Success, message: "", stdout };
|
|
117
|
+
} catch (err) {
|
|
118
|
+
return {
|
|
119
|
+
exitCode: classify(err)?.exitCode ?? -1,
|
|
120
|
+
message: err instanceof Error ? err.message : String(err),
|
|
121
|
+
stdout,
|
|
122
|
+
};
|
|
123
|
+
} finally {
|
|
124
|
+
outSpy.mockRestore();
|
|
125
|
+
errSpy.mockRestore();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
describe("config context set --org", () => {
|
|
130
|
+
it("persists an organization the caller belongs to, which every command then resolves", async () => {
|
|
131
|
+
const outcome = await run("--org", "acme");
|
|
132
|
+
expect(outcome.exitCode).toBe(ExitCode.Success);
|
|
133
|
+
expect(lookups).toBe(1);
|
|
134
|
+
expect(resolveOrganization(load())).toBe("acme");
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it("refuses a slug the backend does not list as the caller's and leaves the config untouched", async () => {
|
|
138
|
+
const before = readFileSync(configFile(), "utf8");
|
|
139
|
+
const outcome = await run("--org", "acmee");
|
|
140
|
+
expect(outcome.exitCode).toBe(ExitCode.NotFound);
|
|
141
|
+
expect(outcome.message).toMatch(/organization 'acmee' is not one you belong to on the 'team' backend/);
|
|
142
|
+
expect(readFileSync(configFile(), "utf8")).toBe(before);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it("clears the context with an empty slug, without asking the backend", async () => {
|
|
146
|
+
await run("--org", "acme");
|
|
147
|
+
const outcome = await run("--org", "");
|
|
148
|
+
expect(outcome.exitCode).toBe(ExitCode.Success);
|
|
149
|
+
expect(lookups).toBe(1);
|
|
150
|
+
expect(resolveOrganization(load())).toBe("stigmer");
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it("is a usage error without --org", async () => {
|
|
154
|
+
const outcome = await run();
|
|
155
|
+
expect(outcome.exitCode).toBe(ExitCode.Usage);
|
|
156
|
+
expect(outcome.message).toMatch(/--org is required/);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
describe("config context show", () => {
|
|
161
|
+
it("names the active backend, not the legacy local/cloud switch", async () => {
|
|
162
|
+
await run("--org", "acme");
|
|
163
|
+
const outcome = await runContext("show", "--json");
|
|
164
|
+
expect(outcome.exitCode).toBe(ExitCode.Success);
|
|
165
|
+
const fields = JSON.parse(outcome.stdout).sections[0].fields as { key: string; value: string }[];
|
|
166
|
+
expect(fields).toEqual([
|
|
167
|
+
{ key: "Organization", value: "acme" },
|
|
168
|
+
{ key: "Backend", value: "team" },
|
|
169
|
+
]);
|
|
170
|
+
});
|
|
171
|
+
});
|