sofia-cli 0.1.2 → 0.1.4

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 (136) hide show
  1. package/README.md +42 -20
  2. package/dist/infra/deploy.sh +193 -0
  3. package/dist/infra/gather-env.sh +211 -0
  4. package/dist/infra/infra/deploy.sh +193 -0
  5. package/dist/infra/infra/gather-env.sh +211 -0
  6. package/dist/infra/infra/main.bicep +90 -0
  7. package/dist/infra/infra/main.bicepparam +18 -0
  8. package/dist/infra/infra/resources.bicep +134 -0
  9. package/dist/infra/infra/teardown.sh +114 -0
  10. package/dist/infra/main.bicep +90 -0
  11. package/dist/infra/main.bicepparam +18 -0
  12. package/dist/infra/resources.bicep +134 -0
  13. package/dist/infra/teardown.sh +114 -0
  14. package/dist/src/cli/developCommand.js +0 -2
  15. package/dist/src/cli/index.js +8 -1
  16. package/dist/src/cli/workshopCommand.js +1 -1
  17. package/dist/src/develop/index.js +1 -1
  18. package/dist/src/develop/pocUtils.js +228 -0
  19. package/dist/src/develop/ralphLoop.js +8 -27
  20. package/dist/src/shared/data/cards.json +655 -670
  21. package/docs/architecture.md +2 -1
  22. package/package.json +5 -3
  23. package/src/cli/developCommand.ts +1 -3
  24. package/src/cli/index.ts +11 -1
  25. package/src/cli/workshopCommand.ts +21 -17
  26. package/src/develop/dynamicScaffolder.ts +36 -30
  27. package/src/develop/index.ts +13 -2
  28. package/src/develop/pocUtils.ts +296 -0
  29. package/src/develop/ralphLoop.ts +8 -28
  30. package/src/develop/templateRegistry.ts +19 -18
  31. package/src/shared/data/cards.json +655 -670
  32. package/tests/e2e/developE2e.spec.ts +3 -61
  33. package/tests/e2e/developFailureE2e.spec.ts +34 -38
  34. package/tests/integration/pocGithubMcp.spec.ts +29 -39
  35. package/tests/integration/pocLocalFallback.spec.ts +29 -39
  36. package/tests/integration/ralphLoopFlow.spec.ts +46 -66
  37. package/tests/integration/ralphLoopPartial.spec.ts +30 -37
  38. package/tests/unit/develop/githubMcpAdapter.spec.ts +0 -134
  39. package/tests/unit/develop/outputValidator.spec.ts +45 -21
  40. package/tests/unit/develop/ralphLoop.spec.ts +58 -94
  41. package/tsconfig.json +2 -1
  42. package/vitest.workspace.ts +5 -0
  43. package/dist/src/develop/pocScaffolder.js +0 -542
  44. package/dist/tests/e2e/developE2e.spec.js +0 -126
  45. package/dist/tests/e2e/developFailureE2e.spec.js +0 -247
  46. package/dist/tests/e2e/developPty.spec.js +0 -75
  47. package/dist/tests/e2e/discoveryWebSearchRelevance.spec.js +0 -84
  48. package/dist/tests/e2e/harness.spec.js +0 -83
  49. package/dist/tests/e2e/mcpLive.spec.js +0 -120
  50. package/dist/tests/e2e/newSession.e2e.spec.js +0 -177
  51. package/dist/tests/e2e/ralphLoopEnrichmentComparison.spec.js +0 -62
  52. package/dist/tests/e2e/workiqEnrichment.spec.js +0 -56
  53. package/dist/tests/e2e/zavaSimulation.spec.js +0 -452
  54. package/dist/tests/fixtures/test-fixture-project/src/add.js +0 -3
  55. package/dist/tests/fixtures/test-fixture-project/tests/failing.test.js +0 -6
  56. package/dist/tests/fixtures/test-fixture-project/tests/hanging.test.js +0 -8
  57. package/dist/tests/fixtures/test-fixture-project/tests/passing.test.js +0 -10
  58. package/dist/tests/fixtures/test-fixture-project/vitest.config.js +0 -6
  59. package/dist/tests/integration/autoStartConversation.spec.js +0 -138
  60. package/dist/tests/integration/defaultCommand.spec.js +0 -147
  61. package/dist/tests/integration/directCommandNonTty.spec.js +0 -224
  62. package/dist/tests/integration/directCommandTty.spec.js +0 -151
  63. package/dist/tests/integration/discoveryEnrichmentFlow.spec.js +0 -175
  64. package/dist/tests/integration/exportArtifacts.spec.js +0 -202
  65. package/dist/tests/integration/exportFallbackFlow.spec.js +0 -99
  66. package/dist/tests/integration/mcpDegradationFlow.spec.js +0 -190
  67. package/dist/tests/integration/mcpTransportFlow.spec.js +0 -139
  68. package/dist/tests/integration/newSessionFlow.spec.js +0 -343
  69. package/dist/tests/integration/pocGithubMcp.spec.js +0 -186
  70. package/dist/tests/integration/pocLocalFallback.spec.js +0 -171
  71. package/dist/tests/integration/pocScaffold.spec.js +0 -163
  72. package/dist/tests/integration/ralphLoopFlow.spec.js +0 -359
  73. package/dist/tests/integration/ralphLoopPartial.spec.js +0 -368
  74. package/dist/tests/integration/resumeAndBacktrack.spec.js +0 -247
  75. package/dist/tests/integration/spinnerLifecycle.spec.js +0 -220
  76. package/dist/tests/integration/summarizationFlow.spec.js +0 -115
  77. package/dist/tests/integration/testRunnerReal.spec.js +0 -52
  78. package/dist/tests/integration/webSearchAgent.spec.js +0 -128
  79. package/dist/tests/live/copilotSdkLive.spec.js +0 -107
  80. package/dist/tests/live/zavaFullWorkshop.spec.js +0 -392
  81. package/dist/tests/setup/loadEnv.js +0 -3
  82. package/dist/tests/unit/cli/developCommand.spec.js +0 -567
  83. package/dist/tests/unit/cli/directCommands.spec.js +0 -279
  84. package/dist/tests/unit/cli/envLoader.spec.js +0 -58
  85. package/dist/tests/unit/cli/ioContext.spec.js +0 -119
  86. package/dist/tests/unit/cli/preflight.spec.js +0 -108
  87. package/dist/tests/unit/cli/statusCommand.spec.js +0 -111
  88. package/dist/tests/unit/cli/workshopClientFallback.spec.js +0 -80
  89. package/dist/tests/unit/cli/workshopCommand.spec.js +0 -328
  90. package/dist/tests/unit/config/vitestEnvSetup.spec.js +0 -13
  91. package/dist/tests/unit/develop/checkpointState.spec.js +0 -315
  92. package/dist/tests/unit/develop/codeGenerator.spec.js +0 -355
  93. package/dist/tests/unit/develop/githubMcpAdapter.spec.js +0 -231
  94. package/dist/tests/unit/develop/mcpContextEnricher.spec.js +0 -433
  95. package/dist/tests/unit/develop/outputValidator.spec.js +0 -119
  96. package/dist/tests/unit/develop/pocScaffolder.spec.js +0 -353
  97. package/dist/tests/unit/develop/ralphLoop.spec.js +0 -1248
  98. package/dist/tests/unit/develop/templateRegistry.spec.js +0 -85
  99. package/dist/tests/unit/develop/testRunner.spec.js +0 -249
  100. package/dist/tests/unit/infraBicep.spec.js +0 -92
  101. package/dist/tests/unit/infraDeploy.spec.js +0 -82
  102. package/dist/tests/unit/infraTeardown.spec.js +0 -63
  103. package/dist/tests/unit/logging/logger.spec.js +0 -43
  104. package/dist/tests/unit/loop/conversationLoop.spec.js +0 -592
  105. package/dist/tests/unit/loop/phaseSummarizer.spec.js +0 -141
  106. package/dist/tests/unit/loop/streamingMarkdown.spec.js +0 -147
  107. package/dist/tests/unit/mcp/mcpManager.spec.js +0 -279
  108. package/dist/tests/unit/mcp/mcpTransport.spec.js +0 -529
  109. package/dist/tests/unit/mcp/retryPolicy.spec.js +0 -218
  110. package/dist/tests/unit/mcp/timeoutValidation.spec.js +0 -46
  111. package/dist/tests/unit/mcp/webSearch.spec.js +0 -567
  112. package/dist/tests/unit/phases/contextSummarizer.spec.js +0 -140
  113. package/dist/tests/unit/phases/discoveryEnricher.repeatCalls.spec.js +0 -93
  114. package/dist/tests/unit/phases/discoveryEnricher.spec.js +0 -411
  115. package/dist/tests/unit/phases/phaseExtractors.spec.js +0 -352
  116. package/dist/tests/unit/phases/phaseHandlers.spec.js +0 -425
  117. package/dist/tests/unit/prompts/promptLoader.spec.js +0 -118
  118. package/dist/tests/unit/schemas/pocSchemas.spec.js +0 -412
  119. package/dist/tests/unit/schemas/session.spec.js +0 -257
  120. package/dist/tests/unit/sessions/exportPaths.spec.js +0 -31
  121. package/dist/tests/unit/sessions/exportWriter.spec.js +0 -655
  122. package/dist/tests/unit/sessions/sessionManager.spec.js +0 -151
  123. package/dist/tests/unit/sessions/sessionStore.spec.js +0 -116
  124. package/dist/tests/unit/shared/activitySpinner.spec.js +0 -175
  125. package/dist/tests/unit/shared/cardsLoader.spec.js +0 -76
  126. package/dist/tests/unit/shared/copilotClient.spec.js +0 -155
  127. package/dist/tests/unit/shared/errorClassifier.spec.js +0 -131
  128. package/dist/tests/unit/shared/events.spec.js +0 -55
  129. package/dist/tests/unit/shared/markdownRenderer.spec.js +0 -35
  130. package/dist/tests/unit/shared/markdownRendererChunks.spec.js +0 -70
  131. package/dist/tests/unit/shared/tableRenderer.spec.js +0 -34
  132. package/dist/vitest.config.js +0 -14
  133. package/dist/vitest.live.config.js +0 -18
  134. package/src/develop/pocScaffolder.ts +0 -646
  135. package/tests/integration/pocScaffold.spec.ts +0 -220
  136. package/tests/unit/develop/pocScaffolder.spec.ts +0 -451
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env bash
2
+ # ──────────────────────────────────────────────────────────────────────────────
3
+ # teardown.sh — Remove Azure AI Foundry resources deployed by deploy.sh
4
+ #
5
+ # Deletes the specified resource group and all contained resources.
6
+ # Clean exit (0) when the resource group doesn't exist.
7
+ #
8
+ # Usage:
9
+ # ./infra/teardown.sh --resource-group <name> [--yes]
10
+ #
11
+ # Exit codes:
12
+ # 0 — Teardown succeeded or resource group doesn't exist
13
+ # 1 — Prerequisite check failed
14
+ # 2 — Deletion failed
15
+ # ──────────────────────────────────────────────────────────────────────────────
16
+ set -euo pipefail
17
+
18
+ # ── Defaults ──────────────────────────────────────────────────────────────────
19
+
20
+ RESOURCE_GROUP=""
21
+ AUTO_CONFIRM=false
22
+
23
+ # ── Parameter parsing ─────────────────────────────────────────────────────────
24
+
25
+ usage() {
26
+ cat <<EOF
27
+ Usage: $(basename "$0") [options]
28
+
29
+ Required:
30
+ -g, --resource-group <name> Resource group to delete
31
+
32
+ Optional:
33
+ --yes Skip confirmation prompt
34
+ -h, --help Show this help message
35
+ EOF
36
+ }
37
+
38
+ while [[ $# -gt 0 ]]; do
39
+ case "$1" in
40
+ -g|--resource-group)
41
+ RESOURCE_GROUP="$2"; shift 2 ;;
42
+ --yes)
43
+ AUTO_CONFIRM=true; shift ;;
44
+ -h|--help)
45
+ usage; exit 0 ;;
46
+ *)
47
+ echo "❌ Unknown option: $1" >&2
48
+ usage >&2
49
+ exit 1 ;;
50
+ esac
51
+ done
52
+
53
+ # ── Validate required parameters ─────────────────────────────────────────────
54
+
55
+ if [[ -z "$RESOURCE_GROUP" ]]; then
56
+ echo "❌ Missing required parameter: --resource-group (-g)" >&2
57
+ usage >&2
58
+ exit 1
59
+ fi
60
+
61
+ # ── Prerequisite checks ──────────────────────────────────────────────────────
62
+
63
+ echo "🔍 Checking prerequisites..."
64
+
65
+ if ! command -v az &>/dev/null; then
66
+ echo "❌ Azure CLI (az) is not installed." >&2
67
+ echo " Install: https://learn.microsoft.com/en-us/cli/azure/install-azure-cli" >&2
68
+ exit 1
69
+ fi
70
+
71
+ if ! az account show &>/dev/null; then
72
+ echo "❌ Not logged in to Azure. Run 'az login' first." >&2
73
+ exit 1
74
+ fi
75
+
76
+ echo "✅ Prerequisites passed"
77
+
78
+ # ── Check if resource group exists ────────────────────────────────────────────
79
+
80
+ echo ""
81
+ echo "🔍 Checking resource group: $RESOURCE_GROUP"
82
+
83
+ RG_EXISTS=$(az group exists --name "$RESOURCE_GROUP" 2>/dev/null || echo "false")
84
+
85
+ if [[ "$RG_EXISTS" != "true" ]]; then
86
+ echo "ℹ️ Resource group '$RESOURCE_GROUP' does not exist. Nothing to delete."
87
+ exit 0
88
+ fi
89
+
90
+ # ── Confirm deletion ─────────────────────────────────────────────────────────
91
+
92
+ if [[ "$AUTO_CONFIRM" != "true" ]]; then
93
+ echo ""
94
+ echo "⚠️ This will delete resource group '$RESOURCE_GROUP' and ALL its resources."
95
+ read -rp "Are you sure? (y/N): " confirm
96
+ if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
97
+ echo "Cancelled."
98
+ exit 0
99
+ fi
100
+ fi
101
+
102
+ # ── Delete resource group ────────────────────────────────────────────────────
103
+
104
+ echo ""
105
+ echo "🗑️ Deleting resource group: $RESOURCE_GROUP"
106
+
107
+ if ! az group delete --name "$RESOURCE_GROUP" --yes --no-wait; then
108
+ echo "" >&2
109
+ echo "❌ Failed to delete resource group '$RESOURCE_GROUP'." >&2
110
+ exit 2
111
+ fi
112
+
113
+ echo "✅ Resource group '$RESOURCE_GROUP' deletion initiated (non-blocking)."
114
+ echo " Resources will be fully removed within a few minutes."
@@ -0,0 +1,90 @@
1
+ // ──────────────────────────────────────────────────────────────────────────────
2
+ // Azure AI Foundry — Basic Agent Setup with Web Search
3
+ //
4
+ // Provisions:
5
+ // 1. Resource Group (auto-created)
6
+ // 2. AI Services account (Foundry) with project management enabled
7
+ // 3. Model deployment (default: gpt-4.1-mini, GlobalStandard SKU)
8
+ // 4. Foundry project (provides the endpoint URL)
9
+ // 5. Account-level capability host (Agents)
10
+ // 6. Project-level capability host (Agents, basic/Microsoft-managed)
11
+ //
12
+ // Usage:
13
+ // az deployment sub create --location <region> --template-file main.bicep \
14
+ // --parameters main.bicepparam
15
+ //
16
+ // See: specs/005-ai-search-deploy/research.md (R1, R2)
17
+ // ──────────────────────────────────────────────────────────────────────────────
18
+
19
+ targetScope = 'subscription'
20
+
21
+ // ── Parameters ───────────────────────────────────────────────────────────────
22
+
23
+ @description('Azure region for all resources. Must support Azure AI Foundry Agent Service.')
24
+ param location string = 'swedencentral'
25
+
26
+ @description('Name of the resource group to create or use.')
27
+ param resourceGroupName string
28
+
29
+ @description('Name of the Azure AI Services (Foundry) account. Used to derive the custom subdomain.')
30
+ param accountName string = 'sofia-foundry'
31
+
32
+ @description('Name of the Foundry project. Provides the endpoint URL for the sofIA CLI.')
33
+ param projectName string = 'sofia-project'
34
+
35
+ @description('Name of the model deployment. Used as FOUNDRY_MODEL_DEPLOYMENT_NAME env var.')
36
+ param modelDeploymentName string = 'gpt-4.1-mini'
37
+
38
+ @description('Model name to deploy. Must support web_search_preview tool type.')
39
+ param modelName string = 'gpt-4.1-mini'
40
+
41
+ @description('Model version to deploy. Pinned for reproducibility.')
42
+ param modelVersion string = '2025-04-14'
43
+
44
+ @description('SKU name for the model deployment. GlobalStandard provides broadest region availability.')
45
+ param modelSkuName string = 'GlobalStandard'
46
+
47
+ @description('SKU capacity (TPM in thousands). Default value=5000.')
48
+ param modelSkuCapacity int = 5000
49
+
50
+ @description('Object ID of the user principal to grant Azure AI Developer access. Obtain with: az ad signed-in-user show --query id -o tsv')
51
+ param userPrincipalId string
52
+
53
+ // ── Unique suffix for globally unique names ──────────────────────────────────
54
+
55
+ var uniqueSuffix = uniqueString(subscription().subscriptionId, resourceGroupName)
56
+
57
+ // ── Resource Group ───────────────────────────────────────────────────────────
58
+
59
+ // Auto-create the resource group if it doesn't exist (FR-002)
60
+ resource rg 'Microsoft.Resources/resourceGroups@2024-03-01' = {
61
+ name: resourceGroupName
62
+ location: location
63
+ }
64
+
65
+ // ── Module: all resources deployed into the resource group ───────────────────
66
+
67
+ module resources 'resources.bicep' = {
68
+ name: 'foundry-resources'
69
+ scope: rg
70
+ params: {
71
+ location: location
72
+ accountName: accountName
73
+ projectName: projectName
74
+ modelDeploymentName: modelDeploymentName
75
+ modelName: modelName
76
+ modelVersion: modelVersion
77
+ modelSkuName: modelSkuName
78
+ modelSkuCapacity: modelSkuCapacity
79
+ uniqueSuffix: uniqueSuffix
80
+ userPrincipalId: userPrincipalId
81
+ }
82
+ }
83
+
84
+ // ── Outputs ──────────────────────────────────────────────────────────────────
85
+
86
+ @description('Foundry project endpoint URL — set as FOUNDRY_PROJECT_ENDPOINT')
87
+ output projectEndpoint string = resources.outputs.projectEndpoint
88
+
89
+ @description('Model deployment name — set as FOUNDRY_MODEL_DEPLOYMENT_NAME')
90
+ output modelDeploymentName string = modelDeploymentName
@@ -0,0 +1,18 @@
1
+ using 'main.bicep'
2
+
3
+ // ── Default parameters for workshop/PoC deployment ───────────────────────────
4
+ // Override at deploy time via:
5
+ // az deployment sub create --parameters resourceGroupName='my-rg' location='eastus'
6
+
7
+ param resourceGroupName = 'sofia-rg'
8
+ param location = 'swedencentral'
9
+ param accountName = 'sofia-foundry'
10
+ param projectName = 'sofia-project'
11
+ param modelDeploymentName = 'gpt-4.1-mini'
12
+ param modelName = 'gpt-4.1-mini'
13
+ param modelVersion = '2025-04-14'
14
+ param modelSkuName = 'GlobalStandard'
15
+ param modelSkuCapacity = 1
16
+
17
+ // Resolved at deploy time by deploy.sh via: az ad signed-in-user show --query id -o tsv
18
+ param userPrincipalId = ''
@@ -0,0 +1,134 @@
1
+ // ──────────────────────────────────────────────────────────────────────────────
2
+ // Resource-group-scoped resources for Azure AI Foundry
3
+ //
4
+ // Deployed as a module from main.bicep (subscription-scoped).
5
+ // ──────────────────────────────────────────────────────────────────────────────
6
+
7
+ // ── Parameters (passed from main.bicep) ──────────────────────────────────────
8
+
9
+ param location string
10
+ param accountName string
11
+ param projectName string
12
+ param modelDeploymentName string
13
+ param modelName string
14
+ param modelVersion string
15
+ param modelSkuName string
16
+ param modelSkuCapacity int
17
+ param uniqueSuffix string
18
+
19
+ @description('Object ID of the user principal to grant Azure AI Developer access. Obtain with: az ad signed-in-user show --query id -o tsv')
20
+ param userPrincipalId string
21
+
22
+ // ── Derived values ───────────────────────────────────────────────────────────
23
+
24
+ var customSubDomainName = '${accountName}-${uniqueSuffix}'
25
+
26
+ // Azure AI Developer — allows creating/managing agents and using models
27
+ // https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#azure-ai-developer
28
+ var azureAIDeveloperRoleId = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '64702f94-c441-49e6-a78b-ef80e0188fee')
29
+
30
+ // ── Resource 1: AI Services Account (Foundry) ────────────────────────────────
31
+ // Top-level Foundry account with project management enabled.
32
+ // kind: AIServices provides access to Foundry Agent Service capabilities.
33
+
34
+ resource aiAccount 'Microsoft.CognitiveServices/accounts@2025-06-01' = {
35
+ name: accountName
36
+ location: location
37
+ kind: 'AIServices'
38
+ identity: {
39
+ type: 'SystemAssigned'
40
+ }
41
+ sku: {
42
+ name: 'S0'
43
+ }
44
+ properties: {
45
+ customSubDomainName: customSubDomainName
46
+ allowProjectManagement: true
47
+ publicNetworkAccess: 'Enabled'
48
+ }
49
+ }
50
+
51
+ // ── Resource 2: Model Deployment ─────────────────────────────────────────────
52
+ // Deploys the language model that will process web search queries.
53
+ // Default: gpt-4.1-mini with GlobalStandard SKU for broadest availability.
54
+
55
+ resource modelDeploy 'Microsoft.CognitiveServices/accounts/deployments@2025-06-01' = {
56
+ parent: aiAccount
57
+ name: modelDeploymentName
58
+ sku: {
59
+ name: modelSkuName
60
+ capacity: modelSkuCapacity
61
+ }
62
+ properties: {
63
+ model: {
64
+ format: 'OpenAI'
65
+ name: modelName
66
+ version: modelVersion
67
+ }
68
+ }
69
+ }
70
+
71
+ // ── Resource 3: Foundry Project ──────────────────────────────────────────────
72
+ // Provides the endpoint URL used by the sofIA CLI (FOUNDRY_PROJECT_ENDPOINT).
73
+
74
+ resource project 'Microsoft.CognitiveServices/accounts/projects@2025-06-01' = {
75
+ parent: aiAccount
76
+ name: projectName
77
+ location: location
78
+ identity: {
79
+ type: 'SystemAssigned'
80
+ }
81
+ properties: {}
82
+ dependsOn: [
83
+ modelDeploy
84
+ ]
85
+ }
86
+
87
+ // ── Resource 4: Account Capability Host (Agents) ─────────────────────────────
88
+ // Enables the Agent Service at the account level.
89
+ // Must be created before the project capability host.
90
+
91
+ resource accountCapabilityHost 'Microsoft.CognitiveServices/accounts/capabilityHosts@2025-06-01' = {
92
+ parent: aiAccount
93
+ name: 'default'
94
+ properties: {
95
+ capabilityHostKind: 'Agents'
96
+ }
97
+ dependsOn: [
98
+ project
99
+ modelDeploy
100
+ ]
101
+ }
102
+
103
+ // ── Resource 5: Project Capability Host (Agents) ─────────────────────────────
104
+ // Enables the Agent Service at the project level.
105
+ // Basic (Microsoft-managed) setup — empty connections array.
106
+
107
+ resource projectCapabilityHost 'Microsoft.CognitiveServices/accounts/projects/capabilityHosts@2025-06-01' = {
108
+ parent: project
109
+ name: 'default'
110
+ properties: {
111
+ capabilityHostKind: 'Agents'
112
+ }
113
+ dependsOn: [
114
+ accountCapabilityHost
115
+ ]
116
+ }
117
+
118
+ // ── Resource 6: Role Assignment — Azure AI Developer for the deploying user ──
119
+ // Grants the deploying user permission to create ephemeral agents, use models,
120
+ // and invoke web_search_preview through the Foundry Agent Service.
121
+
122
+ resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
123
+ name: guid(aiAccount.id, userPrincipalId, azureAIDeveloperRoleId)
124
+ scope: aiAccount
125
+ properties: {
126
+ principalId: userPrincipalId
127
+ roleDefinitionId: azureAIDeveloperRoleId
128
+ principalType: 'User'
129
+ }
130
+ }
131
+
132
+ // ── Outputs ──────────────────────────────────────────────────────────────────
133
+
134
+ output projectEndpoint string = project.properties.endpoints['AI Foundry API']
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env bash
2
+ # ──────────────────────────────────────────────────────────────────────────────
3
+ # teardown.sh — Remove Azure AI Foundry resources deployed by deploy.sh
4
+ #
5
+ # Deletes the specified resource group and all contained resources.
6
+ # Clean exit (0) when the resource group doesn't exist.
7
+ #
8
+ # Usage:
9
+ # ./infra/teardown.sh --resource-group <name> [--yes]
10
+ #
11
+ # Exit codes:
12
+ # 0 — Teardown succeeded or resource group doesn't exist
13
+ # 1 — Prerequisite check failed
14
+ # 2 — Deletion failed
15
+ # ──────────────────────────────────────────────────────────────────────────────
16
+ set -euo pipefail
17
+
18
+ # ── Defaults ──────────────────────────────────────────────────────────────────
19
+
20
+ RESOURCE_GROUP=""
21
+ AUTO_CONFIRM=false
22
+
23
+ # ── Parameter parsing ─────────────────────────────────────────────────────────
24
+
25
+ usage() {
26
+ cat <<EOF
27
+ Usage: $(basename "$0") [options]
28
+
29
+ Required:
30
+ -g, --resource-group <name> Resource group to delete
31
+
32
+ Optional:
33
+ --yes Skip confirmation prompt
34
+ -h, --help Show this help message
35
+ EOF
36
+ }
37
+
38
+ while [[ $# -gt 0 ]]; do
39
+ case "$1" in
40
+ -g|--resource-group)
41
+ RESOURCE_GROUP="$2"; shift 2 ;;
42
+ --yes)
43
+ AUTO_CONFIRM=true; shift ;;
44
+ -h|--help)
45
+ usage; exit 0 ;;
46
+ *)
47
+ echo "❌ Unknown option: $1" >&2
48
+ usage >&2
49
+ exit 1 ;;
50
+ esac
51
+ done
52
+
53
+ # ── Validate required parameters ─────────────────────────────────────────────
54
+
55
+ if [[ -z "$RESOURCE_GROUP" ]]; then
56
+ echo "❌ Missing required parameter: --resource-group (-g)" >&2
57
+ usage >&2
58
+ exit 1
59
+ fi
60
+
61
+ # ── Prerequisite checks ──────────────────────────────────────────────────────
62
+
63
+ echo "🔍 Checking prerequisites..."
64
+
65
+ if ! command -v az &>/dev/null; then
66
+ echo "❌ Azure CLI (az) is not installed." >&2
67
+ echo " Install: https://learn.microsoft.com/en-us/cli/azure/install-azure-cli" >&2
68
+ exit 1
69
+ fi
70
+
71
+ if ! az account show &>/dev/null; then
72
+ echo "❌ Not logged in to Azure. Run 'az login' first." >&2
73
+ exit 1
74
+ fi
75
+
76
+ echo "✅ Prerequisites passed"
77
+
78
+ # ── Check if resource group exists ────────────────────────────────────────────
79
+
80
+ echo ""
81
+ echo "🔍 Checking resource group: $RESOURCE_GROUP"
82
+
83
+ RG_EXISTS=$(az group exists --name "$RESOURCE_GROUP" 2>/dev/null || echo "false")
84
+
85
+ if [[ "$RG_EXISTS" != "true" ]]; then
86
+ echo "ℹ️ Resource group '$RESOURCE_GROUP' does not exist. Nothing to delete."
87
+ exit 0
88
+ fi
89
+
90
+ # ── Confirm deletion ─────────────────────────────────────────────────────────
91
+
92
+ if [[ "$AUTO_CONFIRM" != "true" ]]; then
93
+ echo ""
94
+ echo "⚠️ This will delete resource group '$RESOURCE_GROUP' and ALL its resources."
95
+ read -rp "Are you sure? (y/N): " confirm
96
+ if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
97
+ echo "Cancelled."
98
+ exit 0
99
+ fi
100
+ fi
101
+
102
+ # ── Delete resource group ────────────────────────────────────────────────────
103
+
104
+ echo ""
105
+ echo "🗑️ Deleting resource group: $RESOURCE_GROUP"
106
+
107
+ if ! az group delete --name "$RESOURCE_GROUP" --yes --no-wait; then
108
+ echo "" >&2
109
+ echo "❌ Failed to delete resource group '$RESOURCE_GROUP'." >&2
110
+ exit 2
111
+ fi
112
+
113
+ echo "✅ Resource group '$RESOURCE_GROUP' deletion initiated (non-blocking)."
114
+ echo " Resources will be fully removed within a few minutes."
@@ -17,7 +17,6 @@ import { RalphLoop } from '../develop/ralphLoop.js';
17
17
  import { McpContextEnricher } from '../develop/mcpContextEnricher.js';
18
18
  import { deriveCheckpointState } from '../develop/checkpointState.js';
19
19
  import { createDefaultRegistry, selectTemplate } from '../develop/templateRegistry.js';
20
- import { PocScaffolder } from '../develop/pocScaffolder.js';
21
20
  // ── Validation ────────────────────────────────────────────────────────────────
22
21
  /**
23
22
  * Validate that a session is ready for the Develop phase.
@@ -162,7 +161,6 @@ export async function developCommand(opts, deps) {
162
161
  outputDir,
163
162
  enricher,
164
163
  checkpoint,
165
- scaffolder: new PocScaffolder(template),
166
164
  templateEntry: template,
167
165
  onSessionUpdate: async (updated) => {
168
166
  await store.save(updated);
@@ -8,6 +8,7 @@
8
8
  * - status: display session status
9
9
  * - export: export session artifacts
10
10
  */
11
+ import { existsSync, readFileSync } from 'node:fs';
11
12
  import path from 'node:path';
12
13
  import { fileURLToPath } from 'node:url';
13
14
  import { Command } from 'commander';
@@ -15,6 +16,12 @@ import { loadEnvFile } from './envLoader.js';
15
16
  // ── Load .env from workspace root ──────────────────────────────────────────
16
17
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
17
18
  loadEnvFile(path.resolve(__dirname, '../../.env'));
19
+ // ── Read version from package.json (works from both src/ and dist/) ────────
20
+ let _pkgRoot = __dirname;
21
+ while (_pkgRoot !== path.dirname(_pkgRoot) && !existsSync(path.join(_pkgRoot, 'package.json'))) {
22
+ _pkgRoot = path.dirname(_pkgRoot);
23
+ }
24
+ const { version } = JSON.parse(readFileSync(path.join(_pkgRoot, 'package.json'), 'utf-8'));
18
25
  // ── Build CLI ──────────────────────────────────────────────────────────────
19
26
  /**
20
27
  * Build the Commander program. Accepts optional handler overrides for testing.
@@ -22,7 +29,7 @@ loadEnvFile(path.resolve(__dirname, '../../.env'));
22
29
  */
23
30
  export function buildCli(handlers) {
24
31
  const program = new Command();
25
- program.name('sofia').description('sofIA — AI Discovery Workshop CLI').version('0.1.0');
32
+ program.name('sofia').description('sofIA — AI Discovery Workshop CLI').version(version);
26
33
  // ── Global options ──────────────────────────────────────────────────────
27
34
  program
28
35
  .option('--session <id>', 'Target an existing session')
@@ -14,7 +14,7 @@ import { createDefaultStore } from '../sessions/sessionStore.js';
14
14
  import { createLoopIO } from './ioContext.js';
15
15
  import { createPhaseHandler, getPhaseOrder, getNextPhase } from '../phases/phaseHandlers.js';
16
16
  import { renderMarkdown } from '../shared/markdownRenderer.js';
17
- import { destroyWebSearchSession, isWebSearchConfigured, createWebSearchTool } from '../mcp/webSearch.js';
17
+ import { destroyWebSearchSession, isWebSearchConfigured, createWebSearchTool, } from '../mcp/webSearch.js';
18
18
  import { loadEnvFile } from './envLoader.js';
19
19
  import { loadMcpConfig, McpManager } from '../mcp/mcpManager.js';
20
20
  import { RalphLoop } from '../develop/ralphLoop.js';
@@ -4,7 +4,7 @@
4
4
  * Exports all components of the PoC Generation & Ralph Loop feature (Feature 002).
5
5
  * Orchestrates: scaffold → install → iterate (test → fix → repeat) → complete.
6
6
  */
7
- export { PocScaffolder } from './pocScaffolder.js';
7
+ export { validatePocOutput, initializeGitRepo, scanAndRecordTodos, toKebabCase, buildScaffoldContext, } from './pocUtils.js';
8
8
  export { generateDynamicScaffold } from './dynamicScaffolder.js';
9
9
  export { TestRunner } from './testRunner.js';
10
10
  export { CodeGenerator } from './codeGenerator.js';