@graphorin/cli 0.5.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.
Files changed (109) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +130 -0
  4. package/dist/bin/graphorin.d.ts +1 -0
  5. package/dist/bin/graphorin.js +606 -0
  6. package/dist/bin/graphorin.js.map +1 -0
  7. package/dist/commands/audit.d.ts +59 -0
  8. package/dist/commands/audit.d.ts.map +1 -0
  9. package/dist/commands/audit.js +156 -0
  10. package/dist/commands/audit.js.map +1 -0
  11. package/dist/commands/auth.d.ts +48 -0
  12. package/dist/commands/auth.d.ts.map +1 -0
  13. package/dist/commands/auth.js +148 -0
  14. package/dist/commands/auth.js.map +1 -0
  15. package/dist/commands/consolidator.d.ts +49 -0
  16. package/dist/commands/consolidator.d.ts.map +1 -0
  17. package/dist/commands/consolidator.js +97 -0
  18. package/dist/commands/consolidator.js.map +1 -0
  19. package/dist/commands/doctor.d.ts +64 -0
  20. package/dist/commands/doctor.d.ts.map +1 -0
  21. package/dist/commands/doctor.js +150 -0
  22. package/dist/commands/doctor.js.map +1 -0
  23. package/dist/commands/guard.d.ts +35 -0
  24. package/dist/commands/guard.d.ts.map +1 -0
  25. package/dist/commands/guard.js +86 -0
  26. package/dist/commands/guard.js.map +1 -0
  27. package/dist/commands/index.d.ts +21 -0
  28. package/dist/commands/index.js +22 -0
  29. package/dist/commands/init.d.ts +46 -0
  30. package/dist/commands/init.d.ts.map +1 -0
  31. package/dist/commands/init.js +131 -0
  32. package/dist/commands/init.js.map +1 -0
  33. package/dist/commands/memory.d.ts +243 -0
  34. package/dist/commands/memory.d.ts.map +1 -0
  35. package/dist/commands/memory.js +471 -0
  36. package/dist/commands/memory.js.map +1 -0
  37. package/dist/commands/migrate-config.d.ts +20 -0
  38. package/dist/commands/migrate-config.d.ts.map +1 -0
  39. package/dist/commands/migrate-config.js +48 -0
  40. package/dist/commands/migrate-config.js.map +1 -0
  41. package/dist/commands/migrate-export.d.ts +26 -0
  42. package/dist/commands/migrate-export.d.ts.map +1 -0
  43. package/dist/commands/migrate-export.js +67 -0
  44. package/dist/commands/migrate-export.js.map +1 -0
  45. package/dist/commands/migrate.d.ts +31 -0
  46. package/dist/commands/migrate.d.ts.map +1 -0
  47. package/dist/commands/migrate.js +59 -0
  48. package/dist/commands/migrate.js.map +1 -0
  49. package/dist/commands/pricing.d.ts +66 -0
  50. package/dist/commands/pricing.d.ts.map +1 -0
  51. package/dist/commands/pricing.js +128 -0
  52. package/dist/commands/pricing.js.map +1 -0
  53. package/dist/commands/secrets.d.ts +96 -0
  54. package/dist/commands/secrets.d.ts.map +1 -0
  55. package/dist/commands/secrets.js +182 -0
  56. package/dist/commands/secrets.js.map +1 -0
  57. package/dist/commands/skills.d.ts +58 -0
  58. package/dist/commands/skills.d.ts.map +1 -0
  59. package/dist/commands/skills.js +181 -0
  60. package/dist/commands/skills.js.map +1 -0
  61. package/dist/commands/start.d.ts +51 -0
  62. package/dist/commands/start.d.ts.map +1 -0
  63. package/dist/commands/start.js +122 -0
  64. package/dist/commands/start.js.map +1 -0
  65. package/dist/commands/storage.d.ts +110 -0
  66. package/dist/commands/storage.d.ts.map +1 -0
  67. package/dist/commands/storage.js +274 -0
  68. package/dist/commands/storage.js.map +1 -0
  69. package/dist/commands/telemetry.d.ts +21 -0
  70. package/dist/commands/telemetry.d.ts.map +1 -0
  71. package/dist/commands/telemetry.js +75 -0
  72. package/dist/commands/telemetry.js.map +1 -0
  73. package/dist/commands/token.d.ts +109 -0
  74. package/dist/commands/token.d.ts.map +1 -0
  75. package/dist/commands/token.js +246 -0
  76. package/dist/commands/token.js.map +1 -0
  77. package/dist/commands/tools-lint.d.ts +103 -0
  78. package/dist/commands/tools-lint.d.ts.map +1 -0
  79. package/dist/commands/tools-lint.js +240 -0
  80. package/dist/commands/tools-lint.js.map +1 -0
  81. package/dist/commands/traces.d.ts +33 -0
  82. package/dist/commands/traces.d.ts.map +1 -0
  83. package/dist/commands/traces.js +103 -0
  84. package/dist/commands/traces.js.map +1 -0
  85. package/dist/commands/triggers.d.ts +49 -0
  86. package/dist/commands/triggers.d.ts.map +1 -0
  87. package/dist/commands/triggers.js +129 -0
  88. package/dist/commands/triggers.js.map +1 -0
  89. package/dist/index.d.ts +46 -0
  90. package/dist/index.d.ts.map +1 -0
  91. package/dist/index.js +47 -0
  92. package/dist/index.js.map +1 -0
  93. package/dist/internal/exit.js +17 -0
  94. package/dist/internal/exit.js.map +1 -0
  95. package/dist/internal/load-config.js +84 -0
  96. package/dist/internal/load-config.js.map +1 -0
  97. package/dist/internal/offline.d.ts +58 -0
  98. package/dist/internal/offline.d.ts.map +1 -0
  99. package/dist/internal/offline.js +72 -0
  100. package/dist/internal/offline.js.map +1 -0
  101. package/dist/internal/output.d.ts +56 -0
  102. package/dist/internal/output.d.ts.map +1 -0
  103. package/dist/internal/output.js +86 -0
  104. package/dist/internal/output.js.map +1 -0
  105. package/dist/internal/prompts.js +49 -0
  106. package/dist/internal/prompts.js.map +1 -0
  107. package/dist/internal/store-context.js +69 -0
  108. package/dist/internal/store-context.js.map +1 -0
  109. package/package.json +79 -0
@@ -0,0 +1,46 @@
1
+ import { AuditCommonOptions, AuditExportOptions, AuditExportResult, AuditPruneOptions, AuditVerifyResult, runAuditExport, runAuditPrune, runAuditVerify } from "./commands/audit.js";
2
+ import { AuthCommonOptions, AuthListOptions, AuthLoginOptions, AuthRefreshOptions, AuthRevokeOptions, runAuthList, runAuthLogin, runAuthRefresh, runAuthRevoke, runAuthStatus } from "./commands/auth.js";
3
+ import { CONSOLIDATOR_INVALID_TIER_EXIT, ConsolidatorCommonOptions, ConsolidatorSetTierOptions, ConsolidatorStatusResult, ConsolidatorStopOptions, runConsolidatorSetTier, runConsolidatorStatus, runConsolidatorStop } from "./commands/consolidator.js";
4
+ import { DoctorCommandOptions, DoctorReport, expectedFileModes, runDoctor } from "./commands/doctor.js";
5
+ import { GuardCommonOptions, GuardExplainOptions, GuardExplainResult, GuardStatusEntry, runGuardExplain, runGuardStatus } from "./commands/guard.js";
6
+ import { InitCommandOptions, InitCommandResult, runInit } from "./commands/init.js";
7
+ import { MemoryActivityConflict, MemoryActivityEvent, MemoryActivityOptions, MemoryActivityResult, MemoryCitingInsight, MemoryCommonOptions, MemoryConflictEntry, MemoryHistoryEntry, MemoryInspectEntity, MemoryInspectFact, MemoryInspectOptions, MemoryInspectResult, MemoryMigrateOptions, MemoryReviewItem, MemoryReviewOptions, MemoryReviewResult, MemoryStatusEmbedder, MemoryStatusResult, MemoryWhyOptions, MemoryWhyRecall, MemoryWhyResult, runMemoryActivity, runMemoryInspect, runMemoryMigrate, runMemoryReview, runMemoryStatus, runMemoryWhy } from "./commands/memory.js";
8
+ import { MigrateCommandOptions, MigrateCommandResult, runMigrate } from "./commands/migrate.js";
9
+ import { MigrateConfigOptions, MigrateConfigResult, runMigrateConfig } from "./commands/migrate-config.js";
10
+ import { MigrateExportOptions, MigrateExportResult, runMigrateExport } from "./commands/migrate-export.js";
11
+ import { PricingCommonOptions, PricingDiffOptions, PricingLookupOptions, PricingMissingOptions, PricingRefreshOptions, PricingStatusResult, runPricingDiff, runPricingLookup, runPricingMissing, runPricingRefresh, runPricingStatus } from "./commands/pricing.js";
12
+ import { SecretsCommonOptions, SecretsDeleteOptions, SecretsGetOptions, SecretsGetResult, SecretsListOptions, SecretsRefOptions, SecretsRefResult, SecretsRotateOptions, SecretsSetOptions, runSecretsDelete, runSecretsGet, runSecretsList, runSecretsRef, runSecretsRotate, runSecretsSet } from "./commands/secrets.js";
13
+ import { SkillTrustLevelInput, SkillsAuditOptions, SkillsCommonOptions, SkillsInspectOptions, SkillsInstallOptions, SkillsMigrateFrontmatterOptions, SkillsMigrateFrontmatterResult, runSkillsAudit, runSkillsInspect, runSkillsInstall, runSkillsMigrateFrontmatter } from "./commands/skills.js";
14
+ import { SecretsSourceFlag, StartCommandOptions, runStart } from "./commands/start.js";
15
+ import { StorageCleanupBackupsOptions, StorageCleanupBackupsResult, StorageCommonOptions, StorageEncryptOptions, StorageRekeyOptions, StorageStatusResult, runStorageCleanupBackups, runStorageEncrypt, runStorageRekey, runStorageStatus } from "./commands/storage.js";
16
+ import { TelemetryStatusResult, runTelemetryDisable, runTelemetryEnable, runTelemetryInspect, runTelemetryStatus } from "./commands/telemetry.js";
17
+ import { TokenCommonOptions, TokenCreateOptions, TokenCreateResult, TokenListOptions, TokenRekeyOptions, TokenRevokeOptions, TokenRotateOptions, TokenVerifyOptions, TokenVerifyResult, parseDuration, runTokenCreate, runTokenList, runTokenRekey, runTokenRevoke, runTokenRotate, runTokenVerify } from "./commands/token.js";
18
+ import { ToolsLintOptions, ToolsLintReport, runToolsLint } from "./commands/tools-lint.js";
19
+ import { TracesCommonOptions, TracesPruneOptions, TracesPruneResult, TracesStatusResult, runTracesPrune, runTracesStatus } from "./commands/traces.js";
20
+ import { TriggersCommonOptions, TriggersDisableOptions, TriggersFireOptions, TriggersPruneOptions, TriggersPruneResult, TriggersStatusOptions, runTriggersDisable, runTriggersFire, runTriggersList, runTriggersPrune, runTriggersStatus } from "./commands/triggers.js";
21
+ import "./commands/index.js";
22
+ import { OfflineModeViolationError, assertNoNetworkInOfflineMode, checkOfflineModeBlocked, isOfflineMode } from "./internal/offline.js";
23
+
24
+ //#region src/index.d.ts
25
+ /**
26
+ * `@graphorin/cli` — operator CLI for the Graphorin framework.
27
+ *
28
+ * Phase 14a shipped the minimal `graphorin` binary with three
29
+ * lifecycle commands: `start`, `init`, and `migrate`. Phase 15
30
+ * extended the same binary with the operator surface (`doctor`,
31
+ * `token`, `secrets`, `audit`, `storage`, `memory`, `consolidator`,
32
+ * `triggers`, `auth`, `pricing`, `skills`, `traces`,
33
+ * `migrate-export`, `migrate-config`, `guard`, `telemetry`,
34
+ * `tools lint`).
35
+ *
36
+ * Every subcommand is exported as a typed library function so
37
+ * downstream automations can call them directly without spawning a
38
+ * child process.
39
+ *
40
+ * @packageDocumentation
41
+ */
42
+ /** Canonical version constant. Mirrors the `package.json` version. */
43
+ declare const VERSION = "0.5.0";
44
+ //#endregion
45
+ export { AuditCommonOptions, AuditExportOptions, AuditExportResult, AuditPruneOptions, AuditVerifyResult, AuthCommonOptions, AuthListOptions, AuthLoginOptions, AuthRefreshOptions, AuthRevokeOptions, CONSOLIDATOR_INVALID_TIER_EXIT, ConsolidatorCommonOptions, ConsolidatorSetTierOptions, ConsolidatorStatusResult, ConsolidatorStopOptions, DoctorCommandOptions, DoctorReport, GuardCommonOptions, GuardExplainOptions, GuardExplainResult, GuardStatusEntry, InitCommandOptions, InitCommandResult, MemoryActivityConflict, MemoryActivityEvent, MemoryActivityOptions, MemoryActivityResult, MemoryCitingInsight, MemoryCommonOptions, MemoryConflictEntry, MemoryHistoryEntry, MemoryInspectEntity, MemoryInspectFact, MemoryInspectOptions, MemoryInspectResult, MemoryMigrateOptions, MemoryReviewItem, MemoryReviewOptions, MemoryReviewResult, MemoryStatusEmbedder, MemoryStatusResult, MemoryWhyOptions, MemoryWhyRecall, MemoryWhyResult, MigrateCommandOptions, MigrateCommandResult, MigrateConfigOptions, MigrateConfigResult, MigrateExportOptions, MigrateExportResult, OfflineModeViolationError, PricingCommonOptions, PricingDiffOptions, PricingLookupOptions, PricingMissingOptions, PricingRefreshOptions, PricingStatusResult, SecretsCommonOptions, SecretsDeleteOptions, SecretsGetOptions, SecretsGetResult, SecretsListOptions, SecretsRefOptions, SecretsRefResult, SecretsRotateOptions, SecretsSetOptions, SecretsSourceFlag, SkillTrustLevelInput, SkillsAuditOptions, SkillsCommonOptions, SkillsInspectOptions, SkillsInstallOptions, SkillsMigrateFrontmatterOptions, SkillsMigrateFrontmatterResult, StartCommandOptions, StorageCleanupBackupsOptions, StorageCleanupBackupsResult, StorageCommonOptions, StorageEncryptOptions, StorageRekeyOptions, StorageStatusResult, TelemetryStatusResult, TokenCommonOptions, TokenCreateOptions, TokenCreateResult, TokenListOptions, TokenRekeyOptions, TokenRevokeOptions, TokenRotateOptions, TokenVerifyOptions, TokenVerifyResult, ToolsLintOptions, ToolsLintReport, TracesCommonOptions, TracesPruneOptions, TracesPruneResult, TracesStatusResult, TriggersCommonOptions, TriggersDisableOptions, TriggersFireOptions, TriggersPruneOptions, TriggersPruneResult, TriggersStatusOptions, VERSION, assertNoNetworkInOfflineMode, checkOfflineModeBlocked, expectedFileModes, isOfflineMode, parseDuration, runAuditExport, runAuditPrune, runAuditVerify, runAuthList, runAuthLogin, runAuthRefresh, runAuthRevoke, runAuthStatus, runConsolidatorSetTier, runConsolidatorStatus, runConsolidatorStop, runDoctor, runGuardExplain, runGuardStatus, runInit, runMemoryActivity, runMemoryInspect, runMemoryMigrate, runMemoryReview, runMemoryStatus, runMemoryWhy, runMigrate, runMigrateConfig, runMigrateExport, runPricingDiff, runPricingLookup, runPricingMissing, runPricingRefresh, runPricingStatus, runSecretsDelete, runSecretsGet, runSecretsList, runSecretsRef, runSecretsRotate, runSecretsSet, runSkillsAudit, runSkillsInspect, runSkillsInstall, runSkillsMigrateFrontmatter, runStart, runStorageCleanupBackups, runStorageEncrypt, runStorageRekey, runStorageStatus, runTelemetryDisable, runTelemetryEnable, runTelemetryInspect, runTelemetryStatus, runTokenCreate, runTokenList, runTokenRekey, runTokenRevoke, runTokenRotate, runTokenVerify, runToolsLint, runTracesPrune, runTracesStatus, runTriggersDisable, runTriggersFire, runTriggersList, runTriggersPrune, runTriggersStatus };
46
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAmBa,OAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,47 @@
1
+ import { runAuditExport, runAuditPrune, runAuditVerify } from "./commands/audit.js";
2
+ import { OfflineModeViolationError, assertNoNetworkInOfflineMode, checkOfflineModeBlocked, isOfflineMode } from "./internal/offline.js";
3
+ import { runAuthList, runAuthLogin, runAuthRefresh, runAuthRevoke, runAuthStatus } from "./commands/auth.js";
4
+ import { CONSOLIDATOR_INVALID_TIER_EXIT, runConsolidatorSetTier, runConsolidatorStatus, runConsolidatorStop } from "./commands/consolidator.js";
5
+ import { expectedFileModes, runDoctor } from "./commands/doctor.js";
6
+ import { runGuardExplain, runGuardStatus } from "./commands/guard.js";
7
+ import { runInit } from "./commands/init.js";
8
+ import { runMemoryActivity, runMemoryInspect, runMemoryMigrate, runMemoryReview, runMemoryStatus, runMemoryWhy } from "./commands/memory.js";
9
+ import { runStart } from "./commands/start.js";
10
+ import { runMigrate } from "./commands/migrate.js";
11
+ import { runMigrateConfig } from "./commands/migrate-config.js";
12
+ import { runMigrateExport } from "./commands/migrate-export.js";
13
+ import { runPricingDiff, runPricingLookup, runPricingMissing, runPricingRefresh, runPricingStatus } from "./commands/pricing.js";
14
+ import { runSecretsDelete, runSecretsGet, runSecretsList, runSecretsRef, runSecretsRotate, runSecretsSet } from "./commands/secrets.js";
15
+ import { runSkillsAudit, runSkillsInspect, runSkillsInstall, runSkillsMigrateFrontmatter } from "./commands/skills.js";
16
+ import { runStorageCleanupBackups, runStorageEncrypt, runStorageRekey, runStorageStatus } from "./commands/storage.js";
17
+ import { runTelemetryDisable, runTelemetryEnable, runTelemetryInspect, runTelemetryStatus } from "./commands/telemetry.js";
18
+ import { parseDuration, runTokenCreate, runTokenList, runTokenRekey, runTokenRevoke, runTokenRotate, runTokenVerify } from "./commands/token.js";
19
+ import { runToolsLint } from "./commands/tools-lint.js";
20
+ import { runTracesPrune, runTracesStatus } from "./commands/traces.js";
21
+ import { runTriggersDisable, runTriggersFire, runTriggersList, runTriggersPrune, runTriggersStatus } from "./commands/triggers.js";
22
+ import "./commands/index.js";
23
+
24
+ //#region src/index.ts
25
+ /**
26
+ * `@graphorin/cli` — operator CLI for the Graphorin framework.
27
+ *
28
+ * Phase 14a shipped the minimal `graphorin` binary with three
29
+ * lifecycle commands: `start`, `init`, and `migrate`. Phase 15
30
+ * extended the same binary with the operator surface (`doctor`,
31
+ * `token`, `secrets`, `audit`, `storage`, `memory`, `consolidator`,
32
+ * `triggers`, `auth`, `pricing`, `skills`, `traces`,
33
+ * `migrate-export`, `migrate-config`, `guard`, `telemetry`,
34
+ * `tools lint`).
35
+ *
36
+ * Every subcommand is exported as a typed library function so
37
+ * downstream automations can call them directly without spawning a
38
+ * child process.
39
+ *
40
+ * @packageDocumentation
41
+ */
42
+ /** Canonical version constant. Mirrors the `package.json` version. */
43
+ const VERSION = "0.5.0";
44
+
45
+ //#endregion
46
+ export { CONSOLIDATOR_INVALID_TIER_EXIT, OfflineModeViolationError, VERSION, assertNoNetworkInOfflineMode, checkOfflineModeBlocked, expectedFileModes, isOfflineMode, parseDuration, runAuditExport, runAuditPrune, runAuditVerify, runAuthList, runAuthLogin, runAuthRefresh, runAuthRevoke, runAuthStatus, runConsolidatorSetTier, runConsolidatorStatus, runConsolidatorStop, runDoctor, runGuardExplain, runGuardStatus, runInit, runMemoryActivity, runMemoryInspect, runMemoryMigrate, runMemoryReview, runMemoryStatus, runMemoryWhy, runMigrate, runMigrateConfig, runMigrateExport, runPricingDiff, runPricingLookup, runPricingMissing, runPricingRefresh, runPricingStatus, runSecretsDelete, runSecretsGet, runSecretsList, runSecretsRef, runSecretsRotate, runSecretsSet, runSkillsAudit, runSkillsInspect, runSkillsInstall, runSkillsMigrateFrontmatter, runStart, runStorageCleanupBackups, runStorageEncrypt, runStorageRekey, runStorageStatus, runTelemetryDisable, runTelemetryEnable, runTelemetryInspect, runTelemetryStatus, runTokenCreate, runTokenList, runTokenRekey, runTokenRevoke, runTokenRotate, runTokenVerify, runToolsLint, runTracesPrune, runTracesStatus, runTriggersDisable, runTriggersFire, runTriggersList, runTriggersPrune, runTriggersStatus };
47
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * `@graphorin/cli` — operator CLI for the Graphorin framework.\n *\n * Phase 14a shipped the minimal `graphorin` binary with three\n * lifecycle commands: `start`, `init`, and `migrate`. Phase 15\n * extended the same binary with the operator surface (`doctor`,\n * `token`, `secrets`, `audit`, `storage`, `memory`, `consolidator`,\n * `triggers`, `auth`, `pricing`, `skills`, `traces`,\n * `migrate-export`, `migrate-config`, `guard`, `telemetry`,\n * `tools lint`).\n *\n * Every subcommand is exported as a typed library function so\n * downstream automations can call them directly without spawning a\n * child process.\n *\n * @packageDocumentation\n */\n\n/** Canonical version constant. Mirrors the `package.json` version. */\nexport const VERSION = '0.5.0';\n\nexport * from './commands/index.js';\nexport {\n assertNoNetworkInOfflineMode,\n checkOfflineModeBlocked,\n isOfflineMode,\n OfflineModeViolationError,\n} from './internal/offline.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBA,MAAa,UAAU"}
@@ -0,0 +1,17 @@
1
+ import process from "node:process";
2
+
3
+ //#region src/internal/exit.ts
4
+ /**
5
+ * Numeric exit codes the CLI uses uniformly.
6
+ *
7
+ * @internal
8
+ */
9
+ const EXIT_CODES = Object.freeze({
10
+ OK: 0,
11
+ RECOVERABLE_FAILURE: 1,
12
+ UNSUPPORTED: 2
13
+ });
14
+
15
+ //#endregion
16
+ export { EXIT_CODES };
17
+ //# sourceMappingURL=exit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exit.js","names":[],"sources":["../../src/internal/exit.ts"],"sourcesContent":["/**\n * Shared exit helpers. Phase 15 subcommands fail-fast through\n * {@link fail}; the helper writes the error message via the chosen\n * sink and then calls `process.exit(code)`. Tests stub `process.exit`\n * to convert the call into a thrown sentinel they can assert against.\n *\n * Exit codes follow the small documented contract:\n *\n * - `0` — success (subcommand completed without warnings or with\n * informational warnings only).\n * - `1` — recoverable failure (config invalid, secret missing,\n * threshold exceeded). Operator can fix and re-run.\n * - `2` — unsupported invocation (e.g. `graphorin storage encrypt`\n * when the Phase 16 sub-pack is not installed). Operator must\n * install / configure something before retrying.\n *\n * @internal\n */\n\nimport process from 'node:process';\n\nimport { brand } from './output.js';\n\n/**\n * Numeric exit codes the CLI uses uniformly.\n *\n * @internal\n */\nexport const EXIT_CODES = Object.freeze({\n OK: 0,\n RECOVERABLE_FAILURE: 1,\n UNSUPPORTED: 2,\n} as const);\n\n/**\n * Pretty-print an `Error`-shaped value without leaking secrets, then\n * exit. Re-uses `cause` chains when present.\n *\n * @internal\n */\nexport function fail(\n err: unknown,\n options: {\n readonly code?: number;\n readonly print?: (line: string) => void;\n } = {},\n): never {\n const code = options.code ?? EXIT_CODES.RECOVERABLE_FAILURE;\n const print = options.print ?? ((line: string) => process.stderr.write(`${line}\\n`));\n if (err instanceof Error) {\n const kind = (err as { kind?: string }).kind;\n const prefix = kind === undefined ? '' : `${kind}: `;\n print(brand(`${prefix}${err.message}`));\n const hint = (err as { hint?: string }).hint;\n if (typeof hint === 'string' && hint.length > 0) {\n print(brand(`hint: ${hint}`));\n }\n } else {\n print(brand(`unknown error: ${String(err)}`));\n }\n process.exit(code);\n}\n"],"mappings":";;;;;;;;AA4BA,MAAa,aAAa,OAAO,OAAO;CACtC,IAAI;CACJ,qBAAqB;CACrB,aAAa;CACd,CAAU"}
@@ -0,0 +1,84 @@
1
+ import { readFile, stat } from "node:fs/promises";
2
+ import { isAbsolute, resolve } from "node:path";
3
+ import { pathToFileURL } from "node:url";
4
+
5
+ //#region src/internal/load-config.ts
6
+ /**
7
+ * Tiny config loader. Resolves the path the operator handed in (or
8
+ * the per-platform default) and returns the raw {@link ServerConfigInput}
9
+ * payload — strict validation happens later via
10
+ * `parseServerConfig(...)` from `@graphorin/server`.
11
+ *
12
+ * Supported file kinds (decided by extension):
13
+ *
14
+ * - `*.ts` / `*.mts` / `*.cts` — re-imported through the platform
15
+ * loader; relies on Node's native TS support (or a registered
16
+ * loader) — Phase 14a leaves the operator to wire `tsx`, `ts-node`,
17
+ * or whatever they prefer when shipping a `.ts` config.
18
+ * - `*.js` / `*.mjs` — dynamic `import()`.
19
+ * - `*.json` — `readFile` + `JSON.parse`.
20
+ *
21
+ * The file is expected to default-export an object built via
22
+ * `defineConfig({...})`.
23
+ *
24
+ * @internal
25
+ */
26
+ const DEFAULT_FILENAMES = Object.freeze([
27
+ "graphorin.config.ts",
28
+ "graphorin.config.mjs",
29
+ "graphorin.config.js",
30
+ "graphorin.config.json"
31
+ ]);
32
+ /**
33
+ * Resolve the path the operator passed (or pick the first existing
34
+ * default in `cwd`) and parse the config it exports.
35
+ *
36
+ * @stable
37
+ */
38
+ async function loadConfig(pathArg, options = {}) {
39
+ const cwd = options.cwd ?? process.cwd();
40
+ let absolute;
41
+ if (pathArg !== void 0 && pathArg.length > 0) {
42
+ absolute = isAbsolute(pathArg) ? pathArg : resolve(cwd, pathArg);
43
+ await assertExists(absolute);
44
+ } else absolute = await firstExistingDefault(cwd);
45
+ const config = await importConfig(absolute);
46
+ return Object.freeze({
47
+ path: absolute,
48
+ config
49
+ });
50
+ }
51
+ async function firstExistingDefault(cwd) {
52
+ for (const name of DEFAULT_FILENAMES) {
53
+ const candidate = resolve(cwd, name);
54
+ try {
55
+ await stat(candidate);
56
+ return candidate;
57
+ } catch {}
58
+ }
59
+ throw new Error(`[graphorin/cli] no config file found in '${cwd}'. Looked for: ${DEFAULT_FILENAMES.join(", ")}.`);
60
+ }
61
+ async function assertExists(path) {
62
+ try {
63
+ await stat(path);
64
+ } catch (err) {
65
+ throw new Error(`[graphorin/cli] config file '${path}' not found.`, { cause: err });
66
+ }
67
+ }
68
+ async function importConfig(path) {
69
+ if (path.endsWith(".json")) {
70
+ const raw = await readFile(path, "utf8");
71
+ try {
72
+ return JSON.parse(raw);
73
+ } catch (err) {
74
+ throw new Error(`[graphorin/cli] config '${path}' is not valid JSON.`, { cause: err });
75
+ }
76
+ }
77
+ const mod = await import(pathToFileURL(path).href);
78
+ if (mod.default !== void 0) return mod.default;
79
+ return mod;
80
+ }
81
+
82
+ //#endregion
83
+ export { loadConfig };
84
+ //# sourceMappingURL=load-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-config.js","names":["DEFAULT_FILENAMES: ReadonlyArray<string>","absolute: string"],"sources":["../../src/internal/load-config.ts"],"sourcesContent":["/**\n * Tiny config loader. Resolves the path the operator handed in (or\n * the per-platform default) and returns the raw {@link ServerConfigInput}\n * payload — strict validation happens later via\n * `parseServerConfig(...)` from `@graphorin/server`.\n *\n * Supported file kinds (decided by extension):\n *\n * - `*.ts` / `*.mts` / `*.cts` — re-imported through the platform\n * loader; relies on Node's native TS support (or a registered\n * loader) — Phase 14a leaves the operator to wire `tsx`, `ts-node`,\n * or whatever they prefer when shipping a `.ts` config.\n * - `*.js` / `*.mjs` — dynamic `import()`.\n * - `*.json` — `readFile` + `JSON.parse`.\n *\n * The file is expected to default-export an object built via\n * `defineConfig({...})`.\n *\n * @internal\n */\n\nimport { readFile, stat } from 'node:fs/promises';\nimport { isAbsolute, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nimport type { ServerConfigInput } from '@graphorin/server';\n\n/**\n * @stable\n */\nexport interface LoadConfigOptions {\n /** Override the resolved process.cwd(). Tests inject a fixture root. */\n readonly cwd?: string;\n}\n\n/**\n * @stable\n */\nexport interface LoadedConfig {\n readonly path: string;\n readonly config: ServerConfigInput;\n}\n\nconst DEFAULT_FILENAMES: ReadonlyArray<string> = Object.freeze([\n 'graphorin.config.ts',\n 'graphorin.config.mjs',\n 'graphorin.config.js',\n 'graphorin.config.json',\n]);\n\n/**\n * Resolve the path the operator passed (or pick the first existing\n * default in `cwd`) and parse the config it exports.\n *\n * @stable\n */\nexport async function loadConfig(\n pathArg: string | undefined,\n options: LoadConfigOptions = {},\n): Promise<LoadedConfig> {\n const cwd = options.cwd ?? process.cwd();\n let absolute: string;\n if (pathArg !== undefined && pathArg.length > 0) {\n absolute = isAbsolute(pathArg) ? pathArg : resolve(cwd, pathArg);\n await assertExists(absolute);\n } else {\n absolute = await firstExistingDefault(cwd);\n }\n const config = await importConfig(absolute);\n return Object.freeze({ path: absolute, config });\n}\n\nasync function firstExistingDefault(cwd: string): Promise<string> {\n for (const name of DEFAULT_FILENAMES) {\n const candidate = resolve(cwd, name);\n try {\n await stat(candidate);\n return candidate;\n } catch {}\n }\n throw new Error(\n `[graphorin/cli] no config file found in '${cwd}'. Looked for: ${DEFAULT_FILENAMES.join(', ')}.`,\n );\n}\n\nasync function assertExists(path: string): Promise<void> {\n try {\n await stat(path);\n } catch (err) {\n throw new Error(`[graphorin/cli] config file '${path}' not found.`, { cause: err });\n }\n}\n\nasync function importConfig(path: string): Promise<ServerConfigInput> {\n if (path.endsWith('.json')) {\n const raw = await readFile(path, 'utf8');\n try {\n return JSON.parse(raw) as ServerConfigInput;\n } catch (err) {\n throw new Error(`[graphorin/cli] config '${path}' is not valid JSON.`, { cause: err });\n }\n }\n const url = pathToFileURL(path).href;\n const mod = (await import(url)) as { default?: unknown };\n if (mod.default !== undefined) return mod.default as ServerConfigInput;\n return mod as unknown as ServerConfigInput;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA2CA,MAAMA,oBAA2C,OAAO,OAAO;CAC7D;CACA;CACA;CACA;CACD,CAAC;;;;;;;AAQF,eAAsB,WACpB,SACA,UAA6B,EAAE,EACR;CACvB,MAAM,MAAM,QAAQ,OAAO,QAAQ,KAAK;CACxC,IAAIC;AACJ,KAAI,YAAY,UAAa,QAAQ,SAAS,GAAG;AAC/C,aAAW,WAAW,QAAQ,GAAG,UAAU,QAAQ,KAAK,QAAQ;AAChE,QAAM,aAAa,SAAS;OAE5B,YAAW,MAAM,qBAAqB,IAAI;CAE5C,MAAM,SAAS,MAAM,aAAa,SAAS;AAC3C,QAAO,OAAO,OAAO;EAAE,MAAM;EAAU;EAAQ,CAAC;;AAGlD,eAAe,qBAAqB,KAA8B;AAChE,MAAK,MAAM,QAAQ,mBAAmB;EACpC,MAAM,YAAY,QAAQ,KAAK,KAAK;AACpC,MAAI;AACF,SAAM,KAAK,UAAU;AACrB,UAAO;UACD;;AAEV,OAAM,IAAI,MACR,4CAA4C,IAAI,iBAAiB,kBAAkB,KAAK,KAAK,CAAC,GAC/F;;AAGH,eAAe,aAAa,MAA6B;AACvD,KAAI;AACF,QAAM,KAAK,KAAK;UACT,KAAK;AACZ,QAAM,IAAI,MAAM,gCAAgC,KAAK,eAAe,EAAE,OAAO,KAAK,CAAC;;;AAIvF,eAAe,aAAa,MAA0C;AACpE,KAAI,KAAK,SAAS,QAAQ,EAAE;EAC1B,MAAM,MAAM,MAAM,SAAS,MAAM,OAAO;AACxC,MAAI;AACF,UAAO,KAAK,MAAM,IAAI;WACf,KAAK;AACZ,SAAM,IAAI,MAAM,2BAA2B,KAAK,uBAAuB,EAAE,OAAO,KAAK,CAAC;;;CAI1F,MAAM,MAAO,MAAM,OADP,cAAc,KAAK,CAAC;AAEhC,KAAI,IAAI,YAAY,OAAW,QAAO,IAAI;AAC1C,QAAO"}
@@ -0,0 +1,58 @@
1
+ //#region src/internal/offline.d.ts
2
+ /**
3
+ * `GRAPHORIN_OFFLINE=1` enforcement. The framework promises zero
4
+ * implicit network calls (DEC-154 / ADR-041); the CLI mirrors the
5
+ * promise on the operator-facing side by surfacing the same flag
6
+ * every subcommand obeys.
7
+ *
8
+ * The flag is informational in Phase 14a — the three commands the
9
+ * binary ships do NOT make any outbound network calls. A future
10
+ * phase that exposes a network-using subcommand (e.g. `graphorin
11
+ * pricing refresh`) reads {@link isOfflineMode} to short-circuit.
12
+ *
13
+ * @internal
14
+ */
15
+ /**
16
+ * `true` when `process.env.GRAPHORIN_OFFLINE` is set to `'1'` or
17
+ * `'true'` (case-insensitive). Mirrors the documented contract.
18
+ *
19
+ * @stable
20
+ */
21
+ declare function isOfflineMode(env?: NodeJS.ProcessEnv): boolean;
22
+ /**
23
+ * Throws when the operator opted into offline mode. Phase 14a calls
24
+ * this from every subcommand entry point so the contract is
25
+ * enforced uniformly.
26
+ *
27
+ * @stable
28
+ */
29
+ declare function assertNoNetworkInOfflineMode(operation: string): void;
30
+ /**
31
+ * Phase 15 helper for subcommands that informationally **may** make
32
+ * network calls (e.g. `graphorin auth login`, `graphorin pricing
33
+ * refresh`, `graphorin skills install`). When `GRAPHORIN_OFFLINE=1`
34
+ * is set the helper writes an explanatory branded line through the
35
+ * supplied sink (default: `process.stderr`) and returns `false`,
36
+ * letting the caller short-circuit cleanly without throwing. Returns
37
+ * `true` when the network is permitted.
38
+ *
39
+ * @stable
40
+ */
41
+ declare function checkOfflineModeBlocked(operation: string, options?: {
42
+ readonly print?: (line: string) => void;
43
+ readonly env?: NodeJS.ProcessEnv;
44
+ }): boolean;
45
+ /**
46
+ * Raised when a CLI subcommand attempts a network call while
47
+ * `GRAPHORIN_OFFLINE=1` is set.
48
+ *
49
+ * @stable
50
+ */
51
+ declare class OfflineModeViolationError extends Error {
52
+ readonly kind: "offline-mode-violation";
53
+ readonly operation: string;
54
+ constructor(operation: string);
55
+ }
56
+ //#endregion
57
+ export { OfflineModeViolationError, assertNoNetworkInOfflineMode, checkOfflineModeBlocked, isOfflineMode };
58
+ //# sourceMappingURL=offline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offline.d.ts","names":[],"sources":["../../src/internal/offline.ts"],"sourcesContent":[],"mappings":";;AAoBA;AAcA;AAgBA;AAmBA;;;;;;;;;;;;;;;iBAjDgB,aAAA,OAAmB,MAAA,CAAO;;;;;;;;iBAc1B,4BAAA;;;;;;;;;;;;iBAgBA,uBAAA;;iBAEqD,MAAA,CAAO;;;;;;;;cAiB/D,yBAAA,SAAkC,KAAA"}
@@ -0,0 +1,72 @@
1
+ //#region src/internal/offline.ts
2
+ /**
3
+ * `GRAPHORIN_OFFLINE=1` enforcement. The framework promises zero
4
+ * implicit network calls (DEC-154 / ADR-041); the CLI mirrors the
5
+ * promise on the operator-facing side by surfacing the same flag
6
+ * every subcommand obeys.
7
+ *
8
+ * The flag is informational in Phase 14a — the three commands the
9
+ * binary ships do NOT make any outbound network calls. A future
10
+ * phase that exposes a network-using subcommand (e.g. `graphorin
11
+ * pricing refresh`) reads {@link isOfflineMode} to short-circuit.
12
+ *
13
+ * @internal
14
+ */
15
+ /**
16
+ * `true` when `process.env.GRAPHORIN_OFFLINE` is set to `'1'` or
17
+ * `'true'` (case-insensitive). Mirrors the documented contract.
18
+ *
19
+ * @stable
20
+ */
21
+ function isOfflineMode(env = process.env) {
22
+ const raw = env.GRAPHORIN_OFFLINE;
23
+ if (raw === void 0) return false;
24
+ const normalized = raw.trim().toLowerCase();
25
+ return normalized === "1" || normalized === "true" || normalized === "yes";
26
+ }
27
+ /**
28
+ * Throws when the operator opted into offline mode. Phase 14a calls
29
+ * this from every subcommand entry point so the contract is
30
+ * enforced uniformly.
31
+ *
32
+ * @stable
33
+ */
34
+ function assertNoNetworkInOfflineMode(operation) {
35
+ if (!isOfflineMode()) return;
36
+ throw new OfflineModeViolationError(operation);
37
+ }
38
+ /**
39
+ * Phase 15 helper for subcommands that informationally **may** make
40
+ * network calls (e.g. `graphorin auth login`, `graphorin pricing
41
+ * refresh`, `graphorin skills install`). When `GRAPHORIN_OFFLINE=1`
42
+ * is set the helper writes an explanatory branded line through the
43
+ * supplied sink (default: `process.stderr`) and returns `false`,
44
+ * letting the caller short-circuit cleanly without throwing. Returns
45
+ * `true` when the network is permitted.
46
+ *
47
+ * @stable
48
+ */
49
+ function checkOfflineModeBlocked(operation, options = {}) {
50
+ if (!isOfflineMode(options.env ?? process.env)) return true;
51
+ (options.print ?? ((line) => process.stderr.write(`${line}\n`)))(`[graphorin/cli] GRAPHORIN_OFFLINE=1 — refusing to perform '${operation}'. Unset GRAPHORIN_OFFLINE to opt back in.`);
52
+ return false;
53
+ }
54
+ /**
55
+ * Raised when a CLI subcommand attempts a network call while
56
+ * `GRAPHORIN_OFFLINE=1` is set.
57
+ *
58
+ * @stable
59
+ */
60
+ var OfflineModeViolationError = class extends Error {
61
+ kind = "offline-mode-violation";
62
+ operation;
63
+ constructor(operation) {
64
+ super(`[graphorin/cli] GRAPHORIN_OFFLINE=1 is set; refusing to perform a network operation: ${operation}.`);
65
+ this.name = "OfflineModeViolationError";
66
+ this.operation = operation;
67
+ }
68
+ };
69
+
70
+ //#endregion
71
+ export { OfflineModeViolationError, assertNoNetworkInOfflineMode, checkOfflineModeBlocked, isOfflineMode };
72
+ //# sourceMappingURL=offline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offline.js","names":[],"sources":["../../src/internal/offline.ts"],"sourcesContent":["/**\n * `GRAPHORIN_OFFLINE=1` enforcement. The framework promises zero\n * implicit network calls (DEC-154 / ADR-041); the CLI mirrors the\n * promise on the operator-facing side by surfacing the same flag\n * every subcommand obeys.\n *\n * The flag is informational in Phase 14a — the three commands the\n * binary ships do NOT make any outbound network calls. A future\n * phase that exposes a network-using subcommand (e.g. `graphorin\n * pricing refresh`) reads {@link isOfflineMode} to short-circuit.\n *\n * @internal\n */\n\n/**\n * `true` when `process.env.GRAPHORIN_OFFLINE` is set to `'1'` or\n * `'true'` (case-insensitive). Mirrors the documented contract.\n *\n * @stable\n */\nexport function isOfflineMode(env: NodeJS.ProcessEnv = process.env): boolean {\n const raw = env.GRAPHORIN_OFFLINE;\n if (raw === undefined) return false;\n const normalized = raw.trim().toLowerCase();\n return normalized === '1' || normalized === 'true' || normalized === 'yes';\n}\n\n/**\n * Throws when the operator opted into offline mode. Phase 14a calls\n * this from every subcommand entry point so the contract is\n * enforced uniformly.\n *\n * @stable\n */\nexport function assertNoNetworkInOfflineMode(operation: string): void {\n if (!isOfflineMode()) return;\n throw new OfflineModeViolationError(operation);\n}\n\n/**\n * Phase 15 helper for subcommands that informationally **may** make\n * network calls (e.g. `graphorin auth login`, `graphorin pricing\n * refresh`, `graphorin skills install`). When `GRAPHORIN_OFFLINE=1`\n * is set the helper writes an explanatory branded line through the\n * supplied sink (default: `process.stderr`) and returns `false`,\n * letting the caller short-circuit cleanly without throwing. Returns\n * `true` when the network is permitted.\n *\n * @stable\n */\nexport function checkOfflineModeBlocked(\n operation: string,\n options: { readonly print?: (line: string) => void; readonly env?: NodeJS.ProcessEnv } = {},\n): boolean {\n const env = options.env ?? process.env;\n if (!isOfflineMode(env)) return true;\n const sink = options.print ?? ((line: string) => process.stderr.write(`${line}\\n`));\n sink(\n `[graphorin/cli] GRAPHORIN_OFFLINE=1 — refusing to perform '${operation}'. Unset GRAPHORIN_OFFLINE to opt back in.`,\n );\n return false;\n}\n\n/**\n * Raised when a CLI subcommand attempts a network call while\n * `GRAPHORIN_OFFLINE=1` is set.\n *\n * @stable\n */\nexport class OfflineModeViolationError extends Error {\n readonly kind = 'offline-mode-violation' as const;\n readonly operation: string;\n\n constructor(operation: string) {\n super(\n `[graphorin/cli] GRAPHORIN_OFFLINE=1 is set; refusing to perform a network operation: ${operation}.`,\n );\n this.name = 'OfflineModeViolationError';\n this.operation = operation;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,cAAc,MAAyB,QAAQ,KAAc;CAC3E,MAAM,MAAM,IAAI;AAChB,KAAI,QAAQ,OAAW,QAAO;CAC9B,MAAM,aAAa,IAAI,MAAM,CAAC,aAAa;AAC3C,QAAO,eAAe,OAAO,eAAe,UAAU,eAAe;;;;;;;;;AAUvE,SAAgB,6BAA6B,WAAyB;AACpE,KAAI,CAAC,eAAe,CAAE;AACtB,OAAM,IAAI,0BAA0B,UAAU;;;;;;;;;;;;;AAchD,SAAgB,wBACd,WACA,UAAyF,EAAE,EAClF;AAET,KAAI,CAAC,cADO,QAAQ,OAAO,QAAQ,IACZ,CAAE,QAAO;AAEhC,EADa,QAAQ,WAAW,SAAiB,QAAQ,OAAO,MAAM,GAAG,KAAK,IAAI,GAEhF,8DAA8D,UAAU,4CACzE;AACD,QAAO;;;;;;;;AAST,IAAa,4BAAb,cAA+C,MAAM;CACnD,AAAS,OAAO;CAChB,AAAS;CAET,YAAY,WAAmB;AAC7B,QACE,wFAAwF,UAAU,GACnG;AACD,OAAK,OAAO;AACZ,OAAK,YAAY"}
@@ -0,0 +1,56 @@
1
+ //#region src/internal/output.d.ts
2
+ /**
3
+ * Shared output helpers for Phase 15 subcommands. The CLI keeps three
4
+ * output flavours uniform across every command:
5
+ *
6
+ * 1. **Human** — single-line `[graphorin/cli] ...` messages on stderr
7
+ * (the default path in Phase 14a; preserved for backward
8
+ * compatibility).
9
+ * 2. **JSON** — one structured JSON document per subcommand emitted on
10
+ * stdout when `--json` is set. Phase 15 commands that produce a
11
+ * report (status / list / verify / lookup) ship a stable schema so
12
+ * CI pipelines can consume them.
13
+ * 3. **Stub print sink** — every command accepts an optional
14
+ * `print(line: string)` callback so unit tests can capture output
15
+ * without spying on `process.stderr`.
16
+ *
17
+ * Helpers in this module are intentionally tiny — they exist so the
18
+ * sixteen Phase 15 subcommand groups share one channel surface
19
+ * (single-source-of-truth per Hard Rule 5 in the working plan).
20
+ *
21
+ * @internal
22
+ */
23
+ /**
24
+ * Sink the CLI subcommands write human-readable lines through. The
25
+ * default sink writes a trailing newline to `process.stderr`. Tests
26
+ * inject a buffer.
27
+ *
28
+ * @internal
29
+ */
30
+ type PrintSink = (line: string) => void;
31
+ /**
32
+ * Sink the CLI uses when emitting structured JSON documents. Defaults
33
+ * to writing a single trailing newline to `process.stdout`. Tests
34
+ * inject a buffer.
35
+ *
36
+ * @internal
37
+ */
38
+ type JsonSink = (payload: unknown) => void;
39
+ /**
40
+ * Common output options every Phase 15 command honours.
41
+ *
42
+ * @stable
43
+ */
44
+ interface CommonOutputOptions {
45
+ /** Emit a structured JSON document instead of human-readable text. */
46
+ readonly json?: boolean;
47
+ /** Force `--non-interactive` semantics (skip prompts; require flags / env). */
48
+ readonly nonInteractive?: boolean;
49
+ /** Test seam — capture human lines instead of writing to stderr. */
50
+ readonly print?: PrintSink;
51
+ /** Test seam — capture JSON documents instead of writing to stdout. */
52
+ readonly jsonPrint?: JsonSink;
53
+ }
54
+ //#endregion
55
+ export { CommonOutputOptions };
56
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","names":[],"sources":["../../src/internal/output.ts"],"sourcesContent":[],"mappings":";;AA+BA;AAmBA;AAkBA;;;;;;;;;;;;;;;;;;;;;;;;;KArCY,SAAA;;;;;;;;KAmBA,QAAA;;;;;;UAkBK,mBAAA;;;;;;mBAME;;uBAEI"}
@@ -0,0 +1,86 @@
1
+ import process from "node:process";
2
+
3
+ //#region src/internal/output.ts
4
+ /**
5
+ * Shared output helpers for Phase 15 subcommands. The CLI keeps three
6
+ * output flavours uniform across every command:
7
+ *
8
+ * 1. **Human** — single-line `[graphorin/cli] ...` messages on stderr
9
+ * (the default path in Phase 14a; preserved for backward
10
+ * compatibility).
11
+ * 2. **JSON** — one structured JSON document per subcommand emitted on
12
+ * stdout when `--json` is set. Phase 15 commands that produce a
13
+ * report (status / list / verify / lookup) ship a stable schema so
14
+ * CI pipelines can consume them.
15
+ * 3. **Stub print sink** — every command accepts an optional
16
+ * `print(line: string)` callback so unit tests can capture output
17
+ * without spying on `process.stderr`.
18
+ *
19
+ * Helpers in this module are intentionally tiny — they exist so the
20
+ * sixteen Phase 15 subcommand groups share one channel surface
21
+ * (single-source-of-truth per Hard Rule 5 in the working plan).
22
+ *
23
+ * @internal
24
+ */
25
+ /**
26
+ * Default `PrintSink` — appends a newline and writes to `stderr` so it
27
+ * never collides with the JSON document on `stdout`.
28
+ *
29
+ * @internal
30
+ */
31
+ function defaultPrintSink(line) {
32
+ process.stderr.write(`${line}\n`);
33
+ }
34
+ /**
35
+ * Default `JsonSink` — writes a stable, two-space indented JSON
36
+ * document to `stdout` plus a trailing newline so consumers can split
37
+ * a multi-document stream by lines.
38
+ *
39
+ * @internal
40
+ */
41
+ function defaultJsonSink(payload) {
42
+ process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
43
+ }
44
+ /**
45
+ * Emit either the JSON document or the human report depending on
46
+ * `--json`. Used by every Phase 15 subcommand that produces a single
47
+ * status payload (e.g. `graphorin doctor`, `graphorin token list`).
48
+ *
49
+ * @internal
50
+ */
51
+ function emitReport(options, payload, human) {
52
+ if (options.json === true) {
53
+ (options.jsonPrint ?? defaultJsonSink)(payload);
54
+ return;
55
+ }
56
+ human();
57
+ }
58
+ /**
59
+ * Format a status icon for human reports. The CLI is ASCII-only per
60
+ * the Phase 15 spec (no emoji); the markers are unambiguous so
61
+ * operators see at a glance what a row means.
62
+ *
63
+ * @internal
64
+ */
65
+ function statusMarker(status) {
66
+ switch (status) {
67
+ case "ok": return "[OK]";
68
+ case "warn": return "[WARN]";
69
+ case "fail": return "[FAIL]";
70
+ case "skip": return "[SKIP]";
71
+ case "info": return "[INFO]";
72
+ }
73
+ }
74
+ /**
75
+ * Standardised `[graphorin/cli] <message>` prefix every human-format
76
+ * line carries. Centralised so every command renders the same brand.
77
+ *
78
+ * @internal
79
+ */
80
+ function brand(line) {
81
+ return `[graphorin/cli] ${line}`;
82
+ }
83
+
84
+ //#endregion
85
+ export { brand, defaultJsonSink, defaultPrintSink, emitReport, statusMarker };
86
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","names":[],"sources":["../../src/internal/output.ts"],"sourcesContent":["/**\n * Shared output helpers for Phase 15 subcommands. The CLI keeps three\n * output flavours uniform across every command:\n *\n * 1. **Human** — single-line `[graphorin/cli] ...` messages on stderr\n * (the default path in Phase 14a; preserved for backward\n * compatibility).\n * 2. **JSON** — one structured JSON document per subcommand emitted on\n * stdout when `--json` is set. Phase 15 commands that produce a\n * report (status / list / verify / lookup) ship a stable schema so\n * CI pipelines can consume them.\n * 3. **Stub print sink** — every command accepts an optional\n * `print(line: string)` callback so unit tests can capture output\n * without spying on `process.stderr`.\n *\n * Helpers in this module are intentionally tiny — they exist so the\n * sixteen Phase 15 subcommand groups share one channel surface\n * (single-source-of-truth per Hard Rule 5 in the working plan).\n *\n * @internal\n */\n\nimport process from 'node:process';\n\n/**\n * Sink the CLI subcommands write human-readable lines through. The\n * default sink writes a trailing newline to `process.stderr`. Tests\n * inject a buffer.\n *\n * @internal\n */\nexport type PrintSink = (line: string) => void;\n\n/**\n * Default `PrintSink` — appends a newline and writes to `stderr` so it\n * never collides with the JSON document on `stdout`.\n *\n * @internal\n */\nexport function defaultPrintSink(line: string): void {\n process.stderr.write(`${line}\\n`);\n}\n\n/**\n * Sink the CLI uses when emitting structured JSON documents. Defaults\n * to writing a single trailing newline to `process.stdout`. Tests\n * inject a buffer.\n *\n * @internal\n */\nexport type JsonSink = (payload: unknown) => void;\n\n/**\n * Default `JsonSink` — writes a stable, two-space indented JSON\n * document to `stdout` plus a trailing newline so consumers can split\n * a multi-document stream by lines.\n *\n * @internal\n */\nexport function defaultJsonSink(payload: unknown): void {\n process.stdout.write(`${JSON.stringify(payload, null, 2)}\\n`);\n}\n\n/**\n * Common output options every Phase 15 command honours.\n *\n * @stable\n */\nexport interface CommonOutputOptions {\n /** Emit a structured JSON document instead of human-readable text. */\n readonly json?: boolean;\n /** Force `--non-interactive` semantics (skip prompts; require flags / env). */\n readonly nonInteractive?: boolean;\n /** Test seam — capture human lines instead of writing to stderr. */\n readonly print?: PrintSink;\n /** Test seam — capture JSON documents instead of writing to stdout. */\n readonly jsonPrint?: JsonSink;\n}\n\n/**\n * Emit either the JSON document or the human report depending on\n * `--json`. Used by every Phase 15 subcommand that produces a single\n * status payload (e.g. `graphorin doctor`, `graphorin token list`).\n *\n * @internal\n */\nexport function emitReport(\n options: CommonOutputOptions,\n payload: unknown,\n human: () => void,\n): void {\n if (options.json === true) {\n const sink = options.jsonPrint ?? defaultJsonSink;\n sink(payload);\n return;\n }\n human();\n}\n\n/**\n * Format a status icon for human reports. The CLI is ASCII-only per\n * the Phase 15 spec (no emoji); the markers are unambiguous so\n * operators see at a glance what a row means.\n *\n * @internal\n */\nexport function statusMarker(status: 'ok' | 'warn' | 'fail' | 'skip' | 'info'): string {\n switch (status) {\n case 'ok':\n return '[OK]';\n case 'warn':\n return '[WARN]';\n case 'fail':\n return '[FAIL]';\n case 'skip':\n return '[SKIP]';\n case 'info':\n return '[INFO]';\n }\n}\n\n/**\n * Standardised `[graphorin/cli] <message>` prefix every human-format\n * line carries. Centralised so every command renders the same brand.\n *\n * @internal\n */\nexport function brand(line: string): string {\n return `[graphorin/cli] ${line}`;\n}\n\n/**\n * Convenience helper — writes a branded message via the chosen sink.\n *\n * @internal\n */\nexport function brandedLine(options: CommonOutputOptions, line: string): void {\n const sink = options.print ?? defaultPrintSink;\n sink(brand(line));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCA,SAAgB,iBAAiB,MAAoB;AACnD,SAAQ,OAAO,MAAM,GAAG,KAAK,IAAI;;;;;;;;;AAmBnC,SAAgB,gBAAgB,SAAwB;AACtD,SAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC,IAAI;;;;;;;;;AA0B/D,SAAgB,WACd,SACA,SACA,OACM;AACN,KAAI,QAAQ,SAAS,MAAM;AAEzB,GADa,QAAQ,aAAa,iBAC7B,QAAQ;AACb;;AAEF,QAAO;;;;;;;;;AAUT,SAAgB,aAAa,QAA0D;AACrF,SAAQ,QAAR;EACE,KAAK,KACH,QAAO;EACT,KAAK,OACH,QAAO;EACT,KAAK,OACH,QAAO;EACT,KAAK,OACH,QAAO;EACT,KAAK,OACH,QAAO;;;;;;;;;AAUb,SAAgB,MAAM,MAAsB;AAC1C,QAAO,mBAAmB"}
@@ -0,0 +1,49 @@
1
+ import { stdin, stdout } from "node:process";
2
+ import { createInterface } from "node:readline/promises";
3
+
4
+ //#region src/internal/prompts.ts
5
+ /**
6
+ * Tiny wrapper around `readline` for interactive prompts. Avoids the
7
+ * `enquirer` peer dependency for the minimal Phase 14a surface.
8
+ *
9
+ * @internal
10
+ */
11
+ /**
12
+ * @internal
13
+ */
14
+ async function ask(question, defaultValue) {
15
+ const rl = createInterface({
16
+ input: stdin,
17
+ output: stdout
18
+ });
19
+ try {
20
+ const suffix = defaultValue !== void 0 ? ` (${defaultValue})` : "";
21
+ const answer = await rl.question(`${question}${suffix} `);
22
+ if (answer.length === 0 && defaultValue !== void 0) return defaultValue;
23
+ return answer;
24
+ } finally {
25
+ rl.close();
26
+ }
27
+ }
28
+ /**
29
+ * @internal
30
+ */
31
+ async function confirm(question, defaultValue) {
32
+ const normalized = (await ask(`${question} [${defaultValue ? "Y/n" : "y/N"}]`, defaultValue ? "y" : "n")).trim().toLowerCase();
33
+ if (normalized.length === 0) return defaultValue;
34
+ return normalized === "y" || normalized === "yes";
35
+ }
36
+ /**
37
+ * @internal
38
+ */
39
+ async function select(question, options, defaultValue) {
40
+ const trimmed = (await ask(`${question}\n${options.map((opt, idx) => ` ${idx + 1}. ${opt}${opt === defaultValue ? " (default)" : ""}`).join("\n")}\n>`, defaultValue)).trim();
41
+ const num = Number.parseInt(trimmed, 10);
42
+ if (Number.isFinite(num) && num >= 1 && num <= options.length) return options[num - 1];
43
+ if (options.includes(trimmed)) return trimmed;
44
+ return defaultValue;
45
+ }
46
+
47
+ //#endregion
48
+ export { confirm, select };
49
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","names":[],"sources":["../../src/internal/prompts.ts"],"sourcesContent":["/**\n * Tiny wrapper around `readline` for interactive prompts. Avoids the\n * `enquirer` peer dependency for the minimal Phase 14a surface.\n *\n * @internal\n */\n\nimport { stdin as input, stdout as output } from 'node:process';\nimport { createInterface } from 'node:readline/promises';\n\n/**\n * @internal\n */\nexport async function ask(question: string, defaultValue?: string): Promise<string> {\n const rl = createInterface({ input, output });\n try {\n const suffix = defaultValue !== undefined ? ` (${defaultValue})` : '';\n const answer = await rl.question(`${question}${suffix} `);\n if (answer.length === 0 && defaultValue !== undefined) return defaultValue;\n return answer;\n } finally {\n rl.close();\n }\n}\n\n/**\n * @internal\n */\nexport async function confirm(question: string, defaultValue: boolean): Promise<boolean> {\n const answer = await ask(\n `${question} [${defaultValue ? 'Y/n' : 'y/N'}]`,\n defaultValue ? 'y' : 'n',\n );\n const normalized = answer.trim().toLowerCase();\n if (normalized.length === 0) return defaultValue;\n return normalized === 'y' || normalized === 'yes';\n}\n\n/**\n * @internal\n */\nexport async function select(\n question: string,\n options: ReadonlyArray<string>,\n defaultValue: string,\n): Promise<string> {\n const numbered = options.map(\n (opt, idx) => ` ${idx + 1}. ${opt}${opt === defaultValue ? ' (default)' : ''}`,\n );\n const answer = await ask(`${question}\\n${numbered.join('\\n')}\\n>`, defaultValue);\n const trimmed = answer.trim();\n const num = Number.parseInt(trimmed, 10);\n if (Number.isFinite(num) && num >= 1 && num <= options.length) {\n return options[num - 1] as string;\n }\n if (options.includes(trimmed)) return trimmed;\n return defaultValue;\n}\n"],"mappings":";;;;;;;;;;;;;AAaA,eAAsB,IAAI,UAAkB,cAAwC;CAClF,MAAM,KAAK,gBAAgB;EAAE;EAAO;EAAQ,CAAC;AAC7C,KAAI;EACF,MAAM,SAAS,iBAAiB,SAAY,KAAK,aAAa,KAAK;EACnE,MAAM,SAAS,MAAM,GAAG,SAAS,GAAG,WAAW,OAAO,GAAG;AACzD,MAAI,OAAO,WAAW,KAAK,iBAAiB,OAAW,QAAO;AAC9D,SAAO;WACC;AACR,KAAG,OAAO;;;;;;AAOd,eAAsB,QAAQ,UAAkB,cAAyC;CAKvF,MAAM,cAJS,MAAM,IACnB,GAAG,SAAS,IAAI,eAAe,QAAQ,MAAM,IAC7C,eAAe,MAAM,IACtB,EACyB,MAAM,CAAC,aAAa;AAC9C,KAAI,WAAW,WAAW,EAAG,QAAO;AACpC,QAAO,eAAe,OAAO,eAAe;;;;;AAM9C,eAAsB,OACpB,UACA,SACA,cACiB;CAKjB,MAAM,WADS,MAAM,IAAI,GAAG,SAAS,IAHpB,QAAQ,KACtB,KAAK,QAAQ,KAAK,MAAM,EAAE,IAAI,MAAM,QAAQ,eAAe,eAAe,KAC5E,CACiD,KAAK,KAAK,CAAC,MAAM,aAAa,EACzD,MAAM;CAC7B,MAAM,MAAM,OAAO,SAAS,SAAS,GAAG;AACxC,KAAI,OAAO,SAAS,IAAI,IAAI,OAAO,KAAK,OAAO,QAAQ,OACrD,QAAO,QAAQ,MAAM;AAEvB,KAAI,QAAQ,SAAS,QAAQ,CAAE,QAAO;AACtC,QAAO"}