@runuai/host 0.9.138 → 0.9.140

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.
@@ -734,7 +734,12 @@ function runCodex(home, args) {
734
734
  encoding: "utf8",
735
735
  env: Object.assign({}, process.env, { CODEX_HOME: home }),
736
736
  maxBuffer: 1024 * 1024,
737
- timeout: 5000,
737
+ // Codex's FIRST run on a fresh machine initialises its state (sqlite)
738
+ // before answering; 5 s timed out on every hostless task machine
739
+ // (smoke 10, 2026-09-10: ETIMEDOUT for both homes) and the direct
740
+ // config.toml fallback did the work with an error in the log. A minute
741
+ // is generous for a probe that normally answers in well under a second.
742
+ timeout: 60000,
738
743
  killSignal: "SIGKILL",
739
744
  });
740
745
  }
@@ -61,6 +61,13 @@ export interface CredentialStore {
61
61
  * with Overwrite cannot carry tags). Throws on failure — including when
62
62
  * the identity lacks `ssm:AddTagsToResource`, which older host policies do. */
63
63
  tag(name: string, tags: Record<string, string>): Promise<void>;
64
+ /** The tags on one parameter. Metadata only: `ssm:ListTagsForResource`
65
+ * reveals no value and needs no KMS grant — the sign-in box (ADR-136)
66
+ * rebuilds an account's label from here without ever reading the secret. */
67
+ listTags(name: string): Promise<Record<string, string>>;
68
+ /** Every parameter NAME under `path` (recursive), no values — the
69
+ * `describe-parameters` listing that is allowed on `*` and never decrypts. */
70
+ describeNames(path: string): Promise<string[]>;
64
71
  /** Names and versions under `path` (recursive), NO decryption — the cheap
65
72
  * poll a Uai-operated host runs to notice a broker refresh. */
66
73
  listVersions(path: string): Promise<Array<{ name: string; version: number }>>;
@@ -284,7 +291,7 @@ export class AwsSsmCredentialStore implements CredentialStore {
284
291
  return out;
285
292
  }
286
293
 
287
- async listByName(path: string): Promise<StoredParameter[]> {
294
+ async describeNames(path: string): Promise<string[]> {
288
295
  if (!isParameterName(path)) throw new Error(`invalid parameter path: ${path}`);
289
296
  const described = await this.run([
290
297
  "ssm",
@@ -296,9 +303,34 @@ export class AwsSsmCredentialStore implements CredentialStore {
296
303
  ]);
297
304
  if (described.status !== 0) throw failure("describe-parameters", described);
298
305
  const parsed: unknown = JSON.parse(described.stdout || "[]");
299
- const names = (Array.isArray(parsed) ? parsed : []).filter(
306
+ return (Array.isArray(parsed) ? parsed : []).filter(
300
307
  (name): name is string => typeof name === "string" && name.startsWith(`${path}/`),
301
308
  );
309
+ }
310
+
311
+ async listTags(name: string): Promise<Record<string, string>> {
312
+ if (!isParameterName(name)) throw new Error(`invalid parameter name: ${name}`);
313
+ const result = await this.run([
314
+ "ssm",
315
+ "list-tags-for-resource",
316
+ "--resource-type",
317
+ "Parameter",
318
+ "--resource-id",
319
+ name,
320
+ ]);
321
+ if (result.status !== 0) throw failure("list-tags-for-resource", result);
322
+ const parsed = JSON.parse(result.stdout || "{}") as {
323
+ TagList?: Array<{ Key?: unknown; Value?: unknown }> | null;
324
+ };
325
+ const out: Record<string, string> = {};
326
+ for (const tag of parsed.TagList ?? []) {
327
+ if (typeof tag.Key === "string" && typeof tag.Value === "string") out[tag.Key] = tag.Value;
328
+ }
329
+ return out;
330
+ }
331
+
332
+ async listByName(path: string): Promise<StoredParameter[]> {
333
+ const names = await this.describeNames(path);
302
334
  const out: StoredParameter[] = [];
303
335
  for (const name of names) {
304
336
  const result = await this.run(["ssm", "get-parameter", "--name", name, "--with-decryption"]);